react-grab 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.global.js +344 -256
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.global.js
CHANGED
|
@@ -147,7 +147,9 @@ var ReactGrab = (function (exports) {
|
|
|
147
147
|
};
|
|
148
148
|
const checkAllKeysPressed = (pressedKeys) => {
|
|
149
149
|
if (Array.isArray(key)) {
|
|
150
|
-
return key.every(
|
|
150
|
+
return key.every(
|
|
151
|
+
(keyFromCombo) => checkSingleKeyPressed(keyFromCombo, pressedKeys)
|
|
152
|
+
);
|
|
151
153
|
}
|
|
152
154
|
return checkSingleKeyPressed(key, pressedKeys);
|
|
153
155
|
};
|
|
@@ -214,236 +216,6 @@ var ReactGrab = (function (exports) {
|
|
|
214
216
|
return cleanup;
|
|
215
217
|
};
|
|
216
218
|
|
|
217
|
-
// src/overlay.ts
|
|
218
|
-
var VIEWPORT_MARGIN_PX = 8;
|
|
219
|
-
var LABEL_OFFSET_PX = 6;
|
|
220
|
-
var lerp = (start, end, factor) => {
|
|
221
|
-
return start + (end - start) * factor;
|
|
222
|
-
};
|
|
223
|
-
var SELECTION_LERP_FACTOR = 0.95;
|
|
224
|
-
var createSelectionElement = ({
|
|
225
|
-
borderRadius,
|
|
226
|
-
height,
|
|
227
|
-
transform,
|
|
228
|
-
width,
|
|
229
|
-
x,
|
|
230
|
-
y
|
|
231
|
-
}) => {
|
|
232
|
-
const overlay = document.createElement("div");
|
|
233
|
-
overlay.style.position = "fixed";
|
|
234
|
-
overlay.style.top = `${y}px`;
|
|
235
|
-
overlay.style.left = `${x}px`;
|
|
236
|
-
overlay.style.width = `${width}px`;
|
|
237
|
-
overlay.style.height = `${height}px`;
|
|
238
|
-
overlay.style.borderRadius = borderRadius;
|
|
239
|
-
overlay.style.transform = transform;
|
|
240
|
-
overlay.style.pointerEvents = "none";
|
|
241
|
-
overlay.style.border = "1px solid rgb(210, 57, 192)";
|
|
242
|
-
overlay.style.backgroundColor = "rgba(210, 57, 192, 0.2)";
|
|
243
|
-
overlay.style.zIndex = "2147483646";
|
|
244
|
-
overlay.style.boxSizing = "border-box";
|
|
245
|
-
overlay.style.display = "none";
|
|
246
|
-
return overlay;
|
|
247
|
-
};
|
|
248
|
-
var updateSelectionElement = (element, { borderRadius, height, transform, width, x, y }) => {
|
|
249
|
-
const currentTop = parseFloat(element.style.top) || 0;
|
|
250
|
-
const currentLeft = parseFloat(element.style.left) || 0;
|
|
251
|
-
const currentWidth = parseFloat(element.style.width) || 0;
|
|
252
|
-
const currentHeight = parseFloat(element.style.height) || 0;
|
|
253
|
-
const topValue = `${lerp(currentTop, y, SELECTION_LERP_FACTOR)}px`;
|
|
254
|
-
const leftValue = `${lerp(currentLeft, x, SELECTION_LERP_FACTOR)}px`;
|
|
255
|
-
const widthValue = `${lerp(currentWidth, width, SELECTION_LERP_FACTOR)}px`;
|
|
256
|
-
const heightValue = `${lerp(currentHeight, height, SELECTION_LERP_FACTOR)}px`;
|
|
257
|
-
if (element.style.top !== topValue) {
|
|
258
|
-
element.style.top = topValue;
|
|
259
|
-
}
|
|
260
|
-
if (element.style.left !== leftValue) {
|
|
261
|
-
element.style.left = leftValue;
|
|
262
|
-
}
|
|
263
|
-
if (element.style.width !== widthValue) {
|
|
264
|
-
element.style.width = widthValue;
|
|
265
|
-
}
|
|
266
|
-
if (element.style.height !== heightValue) {
|
|
267
|
-
element.style.height = heightValue;
|
|
268
|
-
}
|
|
269
|
-
if (element.style.borderRadius !== borderRadius) {
|
|
270
|
-
element.style.borderRadius = borderRadius;
|
|
271
|
-
}
|
|
272
|
-
if (element.style.transform !== transform) {
|
|
273
|
-
element.style.transform = transform;
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
var createSelectionOverlay = (root) => {
|
|
277
|
-
const element = createSelectionElement({
|
|
278
|
-
borderRadius: "0px",
|
|
279
|
-
height: 0,
|
|
280
|
-
transform: "none",
|
|
281
|
-
width: 0,
|
|
282
|
-
x: -1e3,
|
|
283
|
-
y: -1e3
|
|
284
|
-
});
|
|
285
|
-
root.appendChild(element);
|
|
286
|
-
let visible = false;
|
|
287
|
-
return {
|
|
288
|
-
hide: () => {
|
|
289
|
-
visible = false;
|
|
290
|
-
element.style.display = "none";
|
|
291
|
-
element.style.pointerEvents = "none";
|
|
292
|
-
},
|
|
293
|
-
isVisible: () => visible,
|
|
294
|
-
show: () => {
|
|
295
|
-
visible = true;
|
|
296
|
-
element.style.display = "block";
|
|
297
|
-
element.style.pointerEvents = "auto";
|
|
298
|
-
},
|
|
299
|
-
update: (selection) => {
|
|
300
|
-
updateSelectionElement(element, selection);
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
};
|
|
304
|
-
var createSpinner = () => {
|
|
305
|
-
const spinner = document.createElement("span");
|
|
306
|
-
spinner.style.display = "inline-block";
|
|
307
|
-
spinner.style.width = "8px";
|
|
308
|
-
spinner.style.height = "8px";
|
|
309
|
-
spinner.style.border = "1.5px solid rgb(210, 57, 192)";
|
|
310
|
-
spinner.style.borderTopColor = "transparent";
|
|
311
|
-
spinner.style.borderRadius = "50%";
|
|
312
|
-
spinner.style.marginRight = "4px";
|
|
313
|
-
spinner.style.verticalAlign = "middle";
|
|
314
|
-
spinner.animate(
|
|
315
|
-
[{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }],
|
|
316
|
-
{
|
|
317
|
-
duration: 600,
|
|
318
|
-
easing: "linear",
|
|
319
|
-
iterations: Infinity
|
|
320
|
-
}
|
|
321
|
-
);
|
|
322
|
-
return spinner;
|
|
323
|
-
};
|
|
324
|
-
var activeIndicator = null;
|
|
325
|
-
var createIndicator = () => {
|
|
326
|
-
const indicator = document.createElement("div");
|
|
327
|
-
indicator.style.position = "fixed";
|
|
328
|
-
indicator.style.top = "calc(8px + env(safe-area-inset-top))";
|
|
329
|
-
indicator.style.padding = "2px 6px";
|
|
330
|
-
indicator.style.backgroundColor = "#fde7f7";
|
|
331
|
-
indicator.style.color = "#b21c8e";
|
|
332
|
-
indicator.style.border = "1px solid #f7c5ec";
|
|
333
|
-
indicator.style.borderRadius = "4px";
|
|
334
|
-
indicator.style.fontSize = "11px";
|
|
335
|
-
indicator.style.fontWeight = "500";
|
|
336
|
-
indicator.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
337
|
-
indicator.style.zIndex = "2147483647";
|
|
338
|
-
indicator.style.pointerEvents = "none";
|
|
339
|
-
indicator.style.opacity = "0";
|
|
340
|
-
indicator.style.transition = "opacity 0.2s ease-in-out";
|
|
341
|
-
indicator.style.display = "flex";
|
|
342
|
-
indicator.style.alignItems = "center";
|
|
343
|
-
indicator.style.maxWidth = "calc(100vw - (16px + env(safe-area-inset-left) + env(safe-area-inset-right)))";
|
|
344
|
-
indicator.style.overflow = "hidden";
|
|
345
|
-
indicator.style.textOverflow = "ellipsis";
|
|
346
|
-
indicator.style.whiteSpace = "nowrap";
|
|
347
|
-
return indicator;
|
|
348
|
-
};
|
|
349
|
-
var showCopyIndicator = (selectionLeftPx, selectionTopPx) => {
|
|
350
|
-
if (activeIndicator) {
|
|
351
|
-
activeIndicator.remove();
|
|
352
|
-
activeIndicator = null;
|
|
353
|
-
}
|
|
354
|
-
const indicator = createIndicator();
|
|
355
|
-
const loadingSpinner = createSpinner();
|
|
356
|
-
const labelText = document.createElement("span");
|
|
357
|
-
labelText.textContent = "Grabbing\u2026";
|
|
358
|
-
indicator.appendChild(loadingSpinner);
|
|
359
|
-
indicator.appendChild(labelText);
|
|
360
|
-
document.body.appendChild(indicator);
|
|
361
|
-
activeIndicator = indicator;
|
|
362
|
-
const indicatorRect = indicator.getBoundingClientRect();
|
|
363
|
-
const viewportWidthPx = window.innerWidth;
|
|
364
|
-
const viewportHeightPx = window.innerHeight;
|
|
365
|
-
let indicatorLeftPx = Math.round(selectionLeftPx);
|
|
366
|
-
let indicatorTopPx = Math.round(selectionTopPx) - indicatorRect.height - LABEL_OFFSET_PX;
|
|
367
|
-
indicatorLeftPx = Math.max(
|
|
368
|
-
VIEWPORT_MARGIN_PX,
|
|
369
|
-
Math.min(
|
|
370
|
-
indicatorLeftPx,
|
|
371
|
-
viewportWidthPx - indicatorRect.width - VIEWPORT_MARGIN_PX
|
|
372
|
-
)
|
|
373
|
-
);
|
|
374
|
-
indicatorTopPx = Math.max(
|
|
375
|
-
VIEWPORT_MARGIN_PX,
|
|
376
|
-
Math.min(
|
|
377
|
-
indicatorTopPx,
|
|
378
|
-
viewportHeightPx - indicatorRect.height - VIEWPORT_MARGIN_PX
|
|
379
|
-
)
|
|
380
|
-
);
|
|
381
|
-
indicator.style.left = `${indicatorLeftPx}px`;
|
|
382
|
-
indicator.style.top = `${indicatorTopPx}px`;
|
|
383
|
-
indicator.style.right = "auto";
|
|
384
|
-
requestAnimationFrame(() => {
|
|
385
|
-
indicator.style.opacity = "1";
|
|
386
|
-
});
|
|
387
|
-
return (tagName) => {
|
|
388
|
-
loadingSpinner.remove();
|
|
389
|
-
const checkmarkIcon = document.createElement("span");
|
|
390
|
-
checkmarkIcon.textContent = "\u2713";
|
|
391
|
-
checkmarkIcon.style.display = "inline-block";
|
|
392
|
-
checkmarkIcon.style.marginRight = "4px";
|
|
393
|
-
checkmarkIcon.style.fontWeight = "600";
|
|
394
|
-
indicator.insertBefore(checkmarkIcon, labelText);
|
|
395
|
-
const tagNameMonospace = document.createElement("span");
|
|
396
|
-
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
397
|
-
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
398
|
-
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
399
|
-
labelText.replaceChildren(
|
|
400
|
-
document.createTextNode("Grabbed "),
|
|
401
|
-
tagNameMonospace
|
|
402
|
-
);
|
|
403
|
-
setTimeout(() => {
|
|
404
|
-
indicator.style.opacity = "0";
|
|
405
|
-
setTimeout(() => {
|
|
406
|
-
indicator.remove();
|
|
407
|
-
if (activeIndicator === indicator) {
|
|
408
|
-
activeIndicator = null;
|
|
409
|
-
}
|
|
410
|
-
}, 200);
|
|
411
|
-
}, 1500);
|
|
412
|
-
};
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
// src/utils/copy-text.ts
|
|
416
|
-
var IS_NAVIGATOR_CLIPBOARD_AVAILABLE = typeof window !== "undefined" && window.navigator.clipboard && window.isSecureContext;
|
|
417
|
-
var copyTextToClipboard = async (text) => {
|
|
418
|
-
if (IS_NAVIGATOR_CLIPBOARD_AVAILABLE) {
|
|
419
|
-
try {
|
|
420
|
-
await navigator.clipboard.writeText(text);
|
|
421
|
-
return true;
|
|
422
|
-
} catch {
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
const textareaElement = document.createElement("textarea");
|
|
426
|
-
textareaElement.value = text;
|
|
427
|
-
textareaElement.setAttribute("readonly", "");
|
|
428
|
-
textareaElement.style.position = "fixed";
|
|
429
|
-
textareaElement.style.top = "-9999px";
|
|
430
|
-
textareaElement.style.opacity = "0";
|
|
431
|
-
textareaElement.style.pointerEvents = "none";
|
|
432
|
-
const doc = document.body || document.documentElement;
|
|
433
|
-
doc.appendChild(textareaElement);
|
|
434
|
-
textareaElement.select();
|
|
435
|
-
textareaElement.setSelectionRange(0, textareaElement.value.length);
|
|
436
|
-
let didCopyToClipboard = false;
|
|
437
|
-
try {
|
|
438
|
-
didCopyToClipboard = document.execCommand("copy");
|
|
439
|
-
} catch {
|
|
440
|
-
didCopyToClipboard = false;
|
|
441
|
-
} finally {
|
|
442
|
-
doc.removeChild(textareaElement);
|
|
443
|
-
}
|
|
444
|
-
return didCopyToClipboard;
|
|
445
|
-
};
|
|
446
|
-
|
|
447
219
|
// node_modules/.pnpm/bippy@0.3.31_@types+react@19.2.2_react@19.2.0/node_modules/bippy/dist/src-R2iEnVC1.js
|
|
448
220
|
var version = "0.3.31";
|
|
449
221
|
var BIPPY_INSTRUMENTATION_STRING = `bippy-${version}`;
|
|
@@ -542,6 +314,7 @@ var ReactGrab = (function (exports) {
|
|
|
542
314
|
return rdtHook;
|
|
543
315
|
};
|
|
544
316
|
var patchRDTHook = (onActive) => {
|
|
317
|
+
if (onActive) onActiveListeners.add(onActive);
|
|
545
318
|
try {
|
|
546
319
|
const rdtHook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
547
320
|
if (!rdtHook) return;
|
|
@@ -622,6 +395,28 @@ var ReactGrab = (function (exports) {
|
|
|
622
395
|
if (!unwrappedType) return null;
|
|
623
396
|
return unwrappedType.displayName || unwrappedType.name || null;
|
|
624
397
|
};
|
|
398
|
+
var instrument = (options) => {
|
|
399
|
+
return getRDTHook(() => {
|
|
400
|
+
const rdtHook = getRDTHook();
|
|
401
|
+
options.onActive?.();
|
|
402
|
+
rdtHook._instrumentationSource = options.name ?? BIPPY_INSTRUMENTATION_STRING;
|
|
403
|
+
const prevOnCommitFiberRoot = rdtHook.onCommitFiberRoot;
|
|
404
|
+
if (options.onCommitFiberRoot) rdtHook.onCommitFiberRoot = (rendererID, root, priority) => {
|
|
405
|
+
if (prevOnCommitFiberRoot) prevOnCommitFiberRoot(rendererID, root, priority);
|
|
406
|
+
options.onCommitFiberRoot?.(rendererID, root, priority);
|
|
407
|
+
};
|
|
408
|
+
const prevOnCommitFiberUnmount = rdtHook.onCommitFiberUnmount;
|
|
409
|
+
if (options.onCommitFiberUnmount) rdtHook.onCommitFiberUnmount = (rendererID, root) => {
|
|
410
|
+
if (prevOnCommitFiberUnmount) prevOnCommitFiberUnmount(rendererID, root);
|
|
411
|
+
options.onCommitFiberUnmount?.(rendererID, root);
|
|
412
|
+
};
|
|
413
|
+
const prevOnPostCommitFiberRoot = rdtHook.onPostCommitFiberRoot;
|
|
414
|
+
if (options.onPostCommitFiberRoot) rdtHook.onPostCommitFiberRoot = (rendererID, root) => {
|
|
415
|
+
if (prevOnPostCommitFiberRoot) prevOnPostCommitFiberRoot(rendererID, root);
|
|
416
|
+
options.onPostCommitFiberRoot?.(rendererID, root);
|
|
417
|
+
};
|
|
418
|
+
});
|
|
419
|
+
};
|
|
625
420
|
var getFiberFromHostInstance = (hostInstance) => {
|
|
626
421
|
const rdtHook = getRDTHook();
|
|
627
422
|
for (const renderer of rdtHook.renderers.values()) try {
|
|
@@ -635,6 +430,7 @@ var ReactGrab = (function (exports) {
|
|
|
635
430
|
}
|
|
636
431
|
return null;
|
|
637
432
|
};
|
|
433
|
+
var _fiberRoots = /* @__PURE__ */ new Set();
|
|
638
434
|
safelyInstallRDTHook();
|
|
639
435
|
|
|
640
436
|
// node_modules/.pnpm/bippy@0.3.31_@types+react@19.2.2_react@19.2.0/node_modules/bippy/dist/source-DWOhEbf2.js
|
|
@@ -2417,14 +2213,18 @@ ${error.stack}`;
|
|
|
2417
2213
|
return matches;
|
|
2418
2214
|
};
|
|
2419
2215
|
|
|
2420
|
-
// src/
|
|
2216
|
+
// src/instrumentation.ts
|
|
2217
|
+
var fiberRoots = _fiberRoots;
|
|
2218
|
+
instrument({
|
|
2219
|
+
onCommitFiberRoot(_, fiberRoot) {
|
|
2220
|
+
fiberRoots.add(fiberRoot);
|
|
2221
|
+
}
|
|
2222
|
+
});
|
|
2421
2223
|
var getStack = async (element) => {
|
|
2422
2224
|
const fiber = getFiberFromHostInstance(element);
|
|
2423
2225
|
if (!fiber) return null;
|
|
2424
2226
|
const stackTrace = getFiberStackTrace(fiber);
|
|
2425
|
-
console.log(stackTrace);
|
|
2426
2227
|
const rawOwnerStack = await getOwnerStack(stackTrace);
|
|
2427
|
-
console.log(rawOwnerStack);
|
|
2428
2228
|
const stack = rawOwnerStack.map((item) => ({
|
|
2429
2229
|
componentName: item.name,
|
|
2430
2230
|
fileName: item.source?.fileName
|
|
@@ -2612,7 +2412,9 @@ ${error.stack}`;
|
|
|
2612
2412
|
lines.push(`${indent2} </${prevSibling.tagName.toLowerCase()}>`);
|
|
2613
2413
|
} else if (targetIndex > 0) {
|
|
2614
2414
|
const indent2 = " ".repeat(ancestors.length);
|
|
2615
|
-
lines.push(
|
|
2415
|
+
lines.push(
|
|
2416
|
+
`${indent2} ... (${targetIndex} element${targetIndex === 1 ? "" : "s"})`
|
|
2417
|
+
);
|
|
2616
2418
|
}
|
|
2617
2419
|
}
|
|
2618
2420
|
}
|
|
@@ -2622,7 +2424,9 @@ ${error.stack}`;
|
|
|
2622
2424
|
const childrenCount = element.children.length;
|
|
2623
2425
|
if (textContent && childrenCount === 0 && textContent.length < 40) {
|
|
2624
2426
|
lines.push(
|
|
2625
|
-
`${indent} ${getElementTag(element)}${textContent}${getClosingTag(
|
|
2427
|
+
`${indent} ${getElementTag(element)}${textContent}${getClosingTag(
|
|
2428
|
+
element
|
|
2429
|
+
)}`
|
|
2626
2430
|
);
|
|
2627
2431
|
} else {
|
|
2628
2432
|
lines.push(indent + " " + getElementTag(element));
|
|
@@ -2659,6 +2463,284 @@ ${error.stack}`;
|
|
|
2659
2463
|
return lines.join("\n");
|
|
2660
2464
|
};
|
|
2661
2465
|
|
|
2466
|
+
// src/overlay.ts
|
|
2467
|
+
var VIEWPORT_MARGIN_PX = 8;
|
|
2468
|
+
var LABEL_OFFSET_PX = 6;
|
|
2469
|
+
var INDICATOR_CLAMP_PADDING_PX = 4;
|
|
2470
|
+
var INDICATOR_SUCCESS_VISIBLE_MS = 1500;
|
|
2471
|
+
var INDICATOR_FADE_MS = 200;
|
|
2472
|
+
var INDICATOR_TOTAL_HIDE_DELAY_MS = INDICATOR_SUCCESS_VISIBLE_MS + INDICATOR_FADE_MS;
|
|
2473
|
+
var lerp = (start, end, factor) => {
|
|
2474
|
+
return start + (end - start) * factor;
|
|
2475
|
+
};
|
|
2476
|
+
var SELECTION_LERP_FACTOR = 0.95;
|
|
2477
|
+
var createSelectionElement = ({
|
|
2478
|
+
borderRadius,
|
|
2479
|
+
height,
|
|
2480
|
+
transform,
|
|
2481
|
+
width,
|
|
2482
|
+
x,
|
|
2483
|
+
y
|
|
2484
|
+
}) => {
|
|
2485
|
+
const overlay = document.createElement("div");
|
|
2486
|
+
overlay.style.position = "fixed";
|
|
2487
|
+
overlay.style.top = `${y}px`;
|
|
2488
|
+
overlay.style.left = `${x}px`;
|
|
2489
|
+
overlay.style.width = `${width}px`;
|
|
2490
|
+
overlay.style.height = `${height}px`;
|
|
2491
|
+
overlay.style.borderRadius = borderRadius;
|
|
2492
|
+
overlay.style.transform = transform;
|
|
2493
|
+
overlay.style.pointerEvents = "none";
|
|
2494
|
+
overlay.style.border = "1px solid rgb(210, 57, 192)";
|
|
2495
|
+
overlay.style.backgroundColor = "rgba(210, 57, 192, 0.2)";
|
|
2496
|
+
overlay.style.zIndex = "2147483646";
|
|
2497
|
+
overlay.style.boxSizing = "border-box";
|
|
2498
|
+
overlay.style.display = "none";
|
|
2499
|
+
return overlay;
|
|
2500
|
+
};
|
|
2501
|
+
var updateSelectionElement = (element, { borderRadius, height, transform, width, x, y }) => {
|
|
2502
|
+
const currentTop = parseFloat(element.style.top) || 0;
|
|
2503
|
+
const currentLeft = parseFloat(element.style.left) || 0;
|
|
2504
|
+
const currentWidth = parseFloat(element.style.width) || 0;
|
|
2505
|
+
const currentHeight = parseFloat(element.style.height) || 0;
|
|
2506
|
+
const topValue = `${lerp(currentTop, y, SELECTION_LERP_FACTOR)}px`;
|
|
2507
|
+
const leftValue = `${lerp(currentLeft, x, SELECTION_LERP_FACTOR)}px`;
|
|
2508
|
+
const widthValue = `${lerp(currentWidth, width, SELECTION_LERP_FACTOR)}px`;
|
|
2509
|
+
const heightValue = `${lerp(currentHeight, height, SELECTION_LERP_FACTOR)}px`;
|
|
2510
|
+
if (element.style.top !== topValue) {
|
|
2511
|
+
element.style.top = topValue;
|
|
2512
|
+
}
|
|
2513
|
+
if (element.style.left !== leftValue) {
|
|
2514
|
+
element.style.left = leftValue;
|
|
2515
|
+
}
|
|
2516
|
+
if (element.style.width !== widthValue) {
|
|
2517
|
+
element.style.width = widthValue;
|
|
2518
|
+
}
|
|
2519
|
+
if (element.style.height !== heightValue) {
|
|
2520
|
+
element.style.height = heightValue;
|
|
2521
|
+
}
|
|
2522
|
+
if (element.style.borderRadius !== borderRadius) {
|
|
2523
|
+
element.style.borderRadius = borderRadius;
|
|
2524
|
+
}
|
|
2525
|
+
if (element.style.transform !== transform) {
|
|
2526
|
+
element.style.transform = transform;
|
|
2527
|
+
}
|
|
2528
|
+
};
|
|
2529
|
+
var createSelectionOverlay = (root) => {
|
|
2530
|
+
const element = createSelectionElement({
|
|
2531
|
+
borderRadius: "0px",
|
|
2532
|
+
height: 0,
|
|
2533
|
+
transform: "none",
|
|
2534
|
+
width: 0,
|
|
2535
|
+
x: -1e3,
|
|
2536
|
+
y: -1e3
|
|
2537
|
+
});
|
|
2538
|
+
root.appendChild(element);
|
|
2539
|
+
let visible = false;
|
|
2540
|
+
return {
|
|
2541
|
+
hide: () => {
|
|
2542
|
+
visible = false;
|
|
2543
|
+
element.style.display = "none";
|
|
2544
|
+
element.style.pointerEvents = "none";
|
|
2545
|
+
},
|
|
2546
|
+
isVisible: () => visible,
|
|
2547
|
+
show: () => {
|
|
2548
|
+
visible = true;
|
|
2549
|
+
element.style.display = "block";
|
|
2550
|
+
element.style.pointerEvents = "auto";
|
|
2551
|
+
},
|
|
2552
|
+
update: (selection) => {
|
|
2553
|
+
updateSelectionElement(element, selection);
|
|
2554
|
+
}
|
|
2555
|
+
};
|
|
2556
|
+
};
|
|
2557
|
+
var createSpinner = () => {
|
|
2558
|
+
const spinner = document.createElement("span");
|
|
2559
|
+
spinner.style.display = "inline-block";
|
|
2560
|
+
spinner.style.width = "8px";
|
|
2561
|
+
spinner.style.height = "8px";
|
|
2562
|
+
spinner.style.border = "1.5px solid rgb(210, 57, 192)";
|
|
2563
|
+
spinner.style.borderTopColor = "transparent";
|
|
2564
|
+
spinner.style.borderRadius = "50%";
|
|
2565
|
+
spinner.style.marginRight = "4px";
|
|
2566
|
+
spinner.style.verticalAlign = "middle";
|
|
2567
|
+
spinner.animate(
|
|
2568
|
+
[{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }],
|
|
2569
|
+
{
|
|
2570
|
+
duration: 600,
|
|
2571
|
+
easing: "linear",
|
|
2572
|
+
iterations: Infinity
|
|
2573
|
+
}
|
|
2574
|
+
);
|
|
2575
|
+
return spinner;
|
|
2576
|
+
};
|
|
2577
|
+
var activeIndicator = null;
|
|
2578
|
+
var createIndicator = () => {
|
|
2579
|
+
const indicator = document.createElement("div");
|
|
2580
|
+
indicator.style.position = "fixed";
|
|
2581
|
+
indicator.style.top = "calc(8px + env(safe-area-inset-top))";
|
|
2582
|
+
indicator.style.padding = "2px 6px";
|
|
2583
|
+
indicator.style.backgroundColor = "#fde7f7";
|
|
2584
|
+
indicator.style.color = "#b21c8e";
|
|
2585
|
+
indicator.style.border = "1px solid #f7c5ec";
|
|
2586
|
+
indicator.style.borderRadius = "4px";
|
|
2587
|
+
indicator.style.fontSize = "11px";
|
|
2588
|
+
indicator.style.fontWeight = "500";
|
|
2589
|
+
indicator.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
2590
|
+
indicator.style.zIndex = "2147483647";
|
|
2591
|
+
indicator.style.pointerEvents = "none";
|
|
2592
|
+
indicator.style.opacity = "0";
|
|
2593
|
+
indicator.style.transition = "opacity 0.2s ease-in-out";
|
|
2594
|
+
indicator.style.display = "flex";
|
|
2595
|
+
indicator.style.alignItems = "center";
|
|
2596
|
+
indicator.style.maxWidth = "calc(100vw - (16px + env(safe-area-inset-left) + env(safe-area-inset-right)))";
|
|
2597
|
+
indicator.style.overflow = "hidden";
|
|
2598
|
+
indicator.style.textOverflow = "ellipsis";
|
|
2599
|
+
indicator.style.whiteSpace = "nowrap";
|
|
2600
|
+
return indicator;
|
|
2601
|
+
};
|
|
2602
|
+
var showLabel = (selectionLeftPx, selectionTopPx, tagName) => {
|
|
2603
|
+
let indicator = activeIndicator;
|
|
2604
|
+
let isNewIndicator = false;
|
|
2605
|
+
if (!indicator) {
|
|
2606
|
+
indicator = createIndicator();
|
|
2607
|
+
document.body.appendChild(indicator);
|
|
2608
|
+
activeIndicator = indicator;
|
|
2609
|
+
isNewIndicator = true;
|
|
2610
|
+
isProcessing = false;
|
|
2611
|
+
}
|
|
2612
|
+
if (!isProcessing) {
|
|
2613
|
+
const labelText = indicator.querySelector("span");
|
|
2614
|
+
if (labelText) {
|
|
2615
|
+
const tagNameMonospace = document.createElement("span");
|
|
2616
|
+
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
2617
|
+
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
2618
|
+
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
2619
|
+
labelText.replaceChildren(tagNameMonospace);
|
|
2620
|
+
} else {
|
|
2621
|
+
const newLabelText = document.createElement("span");
|
|
2622
|
+
const tagNameMonospace = document.createElement("span");
|
|
2623
|
+
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
2624
|
+
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
2625
|
+
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
2626
|
+
newLabelText.appendChild(tagNameMonospace);
|
|
2627
|
+
indicator.appendChild(newLabelText);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
const indicatorRect = indicator.getBoundingClientRect();
|
|
2631
|
+
const viewportWidthPx = window.innerWidth;
|
|
2632
|
+
const viewportHeightPx = window.innerHeight;
|
|
2633
|
+
let indicatorLeftPx = Math.round(selectionLeftPx);
|
|
2634
|
+
let indicatorTopPx = Math.round(selectionTopPx) - indicatorRect.height - LABEL_OFFSET_PX;
|
|
2635
|
+
const CLAMPED_PADDING = INDICATOR_CLAMP_PADDING_PX;
|
|
2636
|
+
const minLeft = VIEWPORT_MARGIN_PX;
|
|
2637
|
+
const minTop = VIEWPORT_MARGIN_PX;
|
|
2638
|
+
const maxLeft = viewportWidthPx - indicatorRect.width - VIEWPORT_MARGIN_PX;
|
|
2639
|
+
const maxTop = viewportHeightPx - indicatorRect.height - VIEWPORT_MARGIN_PX;
|
|
2640
|
+
const willClampLeft = indicatorLeftPx < minLeft;
|
|
2641
|
+
const willClampTop = indicatorTopPx < minTop;
|
|
2642
|
+
const isClamped = willClampLeft || willClampTop;
|
|
2643
|
+
indicatorLeftPx = Math.max(minLeft, Math.min(indicatorLeftPx, maxLeft));
|
|
2644
|
+
indicatorTopPx = Math.max(minTop, Math.min(indicatorTopPx, maxTop));
|
|
2645
|
+
if (isClamped) {
|
|
2646
|
+
indicatorLeftPx += CLAMPED_PADDING;
|
|
2647
|
+
indicatorTopPx += CLAMPED_PADDING;
|
|
2648
|
+
}
|
|
2649
|
+
indicator.style.left = `${indicatorLeftPx}px`;
|
|
2650
|
+
indicator.style.top = `${indicatorTopPx}px`;
|
|
2651
|
+
indicator.style.right = "auto";
|
|
2652
|
+
if (isNewIndicator) {
|
|
2653
|
+
requestAnimationFrame(() => {
|
|
2654
|
+
indicator.style.opacity = "1";
|
|
2655
|
+
});
|
|
2656
|
+
} else if (indicator.style.opacity !== "1") {
|
|
2657
|
+
indicator.style.opacity = "1";
|
|
2658
|
+
}
|
|
2659
|
+
};
|
|
2660
|
+
var isProcessing = false;
|
|
2661
|
+
var updateLabelToProcessing = () => {
|
|
2662
|
+
if (!activeIndicator || isProcessing) return () => {
|
|
2663
|
+
};
|
|
2664
|
+
isProcessing = true;
|
|
2665
|
+
const indicator = activeIndicator;
|
|
2666
|
+
indicator.innerHTML = "";
|
|
2667
|
+
const loadingSpinner = createSpinner();
|
|
2668
|
+
const labelText = document.createElement("span");
|
|
2669
|
+
labelText.textContent = "Grabbing\u2026";
|
|
2670
|
+
indicator.appendChild(loadingSpinner);
|
|
2671
|
+
indicator.appendChild(labelText);
|
|
2672
|
+
return (tagName) => {
|
|
2673
|
+
if (!activeIndicator) {
|
|
2674
|
+
isProcessing = false;
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2677
|
+
indicator.textContent = "";
|
|
2678
|
+
const checkmarkIcon = document.createElement("span");
|
|
2679
|
+
checkmarkIcon.textContent = "\u2713";
|
|
2680
|
+
checkmarkIcon.style.display = "inline-block";
|
|
2681
|
+
checkmarkIcon.style.marginRight = "4px";
|
|
2682
|
+
checkmarkIcon.style.fontWeight = "600";
|
|
2683
|
+
const newLabelText = document.createElement("span");
|
|
2684
|
+
const tagNameMonospace = document.createElement("span");
|
|
2685
|
+
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
2686
|
+
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
2687
|
+
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
2688
|
+
newLabelText.appendChild(document.createTextNode("Grabbed "));
|
|
2689
|
+
newLabelText.appendChild(tagNameMonospace);
|
|
2690
|
+
indicator.appendChild(checkmarkIcon);
|
|
2691
|
+
indicator.appendChild(newLabelText);
|
|
2692
|
+
setTimeout(() => {
|
|
2693
|
+
indicator.style.opacity = "0";
|
|
2694
|
+
setTimeout(() => {
|
|
2695
|
+
indicator.remove();
|
|
2696
|
+
if (activeIndicator === indicator) {
|
|
2697
|
+
activeIndicator = null;
|
|
2698
|
+
}
|
|
2699
|
+
isProcessing = false;
|
|
2700
|
+
}, INDICATOR_FADE_MS);
|
|
2701
|
+
}, INDICATOR_SUCCESS_VISIBLE_MS);
|
|
2702
|
+
};
|
|
2703
|
+
};
|
|
2704
|
+
var hideLabel = () => {
|
|
2705
|
+
if (activeIndicator) {
|
|
2706
|
+
activeIndicator.remove();
|
|
2707
|
+
activeIndicator = null;
|
|
2708
|
+
}
|
|
2709
|
+
isProcessing = false;
|
|
2710
|
+
};
|
|
2711
|
+
|
|
2712
|
+
// src/utils/copy-text.ts
|
|
2713
|
+
var IS_NAVIGATOR_CLIPBOARD_AVAILABLE = typeof window !== "undefined" && window.navigator.clipboard && window.isSecureContext;
|
|
2714
|
+
var copyTextToClipboard = async (text) => {
|
|
2715
|
+
if (IS_NAVIGATOR_CLIPBOARD_AVAILABLE) {
|
|
2716
|
+
try {
|
|
2717
|
+
await navigator.clipboard.writeText(text);
|
|
2718
|
+
return true;
|
|
2719
|
+
} catch {
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
const textareaElement = document.createElement("textarea");
|
|
2723
|
+
textareaElement.value = text;
|
|
2724
|
+
textareaElement.setAttribute("readonly", "");
|
|
2725
|
+
textareaElement.style.position = "fixed";
|
|
2726
|
+
textareaElement.style.top = "-9999px";
|
|
2727
|
+
textareaElement.style.opacity = "0";
|
|
2728
|
+
textareaElement.style.pointerEvents = "none";
|
|
2729
|
+
const doc = document.body || document.documentElement;
|
|
2730
|
+
doc.appendChild(textareaElement);
|
|
2731
|
+
textareaElement.select();
|
|
2732
|
+
textareaElement.setSelectionRange(0, textareaElement.value.length);
|
|
2733
|
+
let didCopyToClipboard = false;
|
|
2734
|
+
try {
|
|
2735
|
+
didCopyToClipboard = document.execCommand("copy");
|
|
2736
|
+
} catch {
|
|
2737
|
+
didCopyToClipboard = false;
|
|
2738
|
+
} finally {
|
|
2739
|
+
doc.removeChild(textareaElement);
|
|
2740
|
+
}
|
|
2741
|
+
return didCopyToClipboard;
|
|
2742
|
+
};
|
|
2743
|
+
|
|
2662
2744
|
// src/utils/is-element-visible.ts
|
|
2663
2745
|
var isElementVisible = (element, computedStyle = window.getComputedStyle(element)) => {
|
|
2664
2746
|
return computedStyle.display !== "none" && computedStyle.visibility !== "hidden" && computedStyle.opacity !== "0";
|
|
@@ -2811,7 +2893,7 @@ ${error.stack}`;
|
|
|
2811
2893
|
}
|
|
2812
2894
|
const resolvedOptions = {
|
|
2813
2895
|
enabled: true,
|
|
2814
|
-
hotkey: "Meta",
|
|
2896
|
+
hotkey: ["Meta", "C"],
|
|
2815
2897
|
keyHoldDuration: 500,
|
|
2816
2898
|
...options
|
|
2817
2899
|
};
|
|
@@ -2830,9 +2912,6 @@ ${error.stack}`;
|
|
|
2830
2912
|
}
|
|
2831
2913
|
return isKeyPressed(resolvedOptions.hotkey);
|
|
2832
2914
|
};
|
|
2833
|
-
const isCopyHotkeyPressed = () => {
|
|
2834
|
-
return isKeyPressed("Meta") && isKeyPressed("C");
|
|
2835
|
-
};
|
|
2836
2915
|
let cleanupActivationHotkeyWatcher = null;
|
|
2837
2916
|
const handleKeyStateChange = (pressedKeys) => {
|
|
2838
2917
|
const { overlayMode } = libStore.getState();
|
|
@@ -2869,13 +2948,6 @@ ${error.stack}`;
|
|
|
2869
2948
|
}
|
|
2870
2949
|
return;
|
|
2871
2950
|
}
|
|
2872
|
-
if (isCopyHotkeyPressed() && overlayMode === "visible") {
|
|
2873
|
-
libStore.setState((state) => ({
|
|
2874
|
-
...state,
|
|
2875
|
-
overlayMode: "copying"
|
|
2876
|
-
}));
|
|
2877
|
-
return;
|
|
2878
|
-
}
|
|
2879
2951
|
const isActivationHotkeyPressed = checkIsActivationHotkeyPressed();
|
|
2880
2952
|
if (!isActivationHotkeyPressed) {
|
|
2881
2953
|
if (cleanupActivationHotkeyWatcher) {
|
|
@@ -2949,8 +3021,7 @@ ${error.stack}`;
|
|
|
2949
3021
|
return null;
|
|
2950
3022
|
};
|
|
2951
3023
|
const handleCopy = async (element) => {
|
|
2952
|
-
const
|
|
2953
|
-
const cleanupCopyIndicator = showCopyIndicator(rect.left, rect.top);
|
|
3024
|
+
const cleanupIndicator = updateLabelToProcessing();
|
|
2954
3025
|
try {
|
|
2955
3026
|
const stack = await getStack(element);
|
|
2956
3027
|
const htmlSnippet = getHTMLSnippet(element);
|
|
@@ -2958,16 +3029,22 @@ ${error.stack}`;
|
|
|
2958
3029
|
if (stack) {
|
|
2959
3030
|
const filteredStack = filterStack(stack);
|
|
2960
3031
|
const serializedStack = serializeStack(filteredStack);
|
|
2961
|
-
text = `${
|
|
3032
|
+
text = `${htmlSnippet}
|
|
2962
3033
|
|
|
2963
|
-
|
|
3034
|
+
Component owner stack:
|
|
3035
|
+
${serializedStack}`;
|
|
2964
3036
|
}
|
|
2965
|
-
await copyTextToClipboard(
|
|
2966
|
-
|
|
3037
|
+
await copyTextToClipboard(
|
|
3038
|
+
`
|
|
3039
|
+
|
|
3040
|
+
<referenced_element>
|
|
3041
|
+
${text}
|
|
3042
|
+
</referenced_element>`
|
|
3043
|
+
);
|
|
2967
3044
|
const tagName = (element.tagName || "").toLowerCase();
|
|
2968
|
-
|
|
3045
|
+
cleanupIndicator(tagName);
|
|
2969
3046
|
} catch {
|
|
2970
|
-
|
|
3047
|
+
cleanupIndicator();
|
|
2971
3048
|
}
|
|
2972
3049
|
};
|
|
2973
3050
|
const handleRender = throttle((state) => {
|
|
@@ -2975,6 +3052,9 @@ ${text}`);
|
|
|
2975
3052
|
if (overlayMode === "hidden") {
|
|
2976
3053
|
if (selectionOverlay.isVisible()) {
|
|
2977
3054
|
selectionOverlay.hide();
|
|
3055
|
+
if (!isCopying) {
|
|
3056
|
+
hideLabel();
|
|
3057
|
+
}
|
|
2978
3058
|
hoveredElement = null;
|
|
2979
3059
|
}
|
|
2980
3060
|
return;
|
|
@@ -3000,7 +3080,10 @@ ${text}`);
|
|
|
3000
3080
|
...state2,
|
|
3001
3081
|
overlayMode: "hidden"
|
|
3002
3082
|
}));
|
|
3003
|
-
|
|
3083
|
+
selectionOverlay.hide();
|
|
3084
|
+
window.setTimeout(() => {
|
|
3085
|
+
isCopying = false;
|
|
3086
|
+
}, INDICATOR_TOTAL_HIDE_DELAY_MS);
|
|
3004
3087
|
});
|
|
3005
3088
|
}
|
|
3006
3089
|
return;
|
|
@@ -3009,10 +3092,14 @@ ${text}`);
|
|
|
3009
3092
|
if (!element) {
|
|
3010
3093
|
if (selectionOverlay.isVisible()) {
|
|
3011
3094
|
selectionOverlay.hide();
|
|
3095
|
+
if (!isCopying) {
|
|
3096
|
+
hideLabel();
|
|
3097
|
+
}
|
|
3012
3098
|
}
|
|
3013
3099
|
hoveredElement = null;
|
|
3014
3100
|
return;
|
|
3015
3101
|
}
|
|
3102
|
+
const tagName = (element.tagName || "").toLowerCase();
|
|
3016
3103
|
hoveredElement = element;
|
|
3017
3104
|
const rect = element.getBoundingClientRect();
|
|
3018
3105
|
const computedStyle = window.getComputedStyle(element);
|
|
@@ -3029,6 +3116,7 @@ ${text}`);
|
|
|
3029
3116
|
if (!selectionOverlay.isVisible()) {
|
|
3030
3117
|
selectionOverlay.show();
|
|
3031
3118
|
}
|
|
3119
|
+
showLabel(rect.left, rect.top, tagName);
|
|
3032
3120
|
}, 10);
|
|
3033
3121
|
const cleanupRenderSubscription = libStore.subscribe((state) => {
|
|
3034
3122
|
scheduleRunWhenIdle(() => {
|