Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/scan/src/web/views/inspector/overlay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ export const ScanOverlay = () => {
<>
<div
ref={refEventCatcher}
className={cn('fixed inset-0 w-screen h-screen', 'z-[214748365]')}
className={cn('fixed top-0 left-0 w-screen h-screen', 'z-[214748365]')}
// DO NOT DO NOT DO NOT REMOVE THE STYLE IT WILL CAUSE MASSIVE PERFORMANCE ISSUES https://x.com/RobKnight__/status/1897524145157439558
style={{
pointerEvents: 'none',
Expand All @@ -721,7 +721,7 @@ export const ScanOverlay = () => {
dir="ltr"
className={cn(
'react-scan-inspector-overlay',
'fixed inset-0 w-screen h-screen',
'fixed top-0 left-0 w-screen h-screen',
Copy link
Contributor Author

@tengweiherr tengweiherr Apr 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to fix the following canvas positioning issue in RTL.

issue-1.mov

Notice that the initial render's outlines flushing is fine because of top-0 left-0 in here

'pointer-events-none',
'z-[214748367]',
)}
Expand Down
97 changes: 72 additions & 25 deletions packages/scan/src/web/widget/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export const calculatePosition = (
width: number,
height: number,
): Position => {
const isRTL = getComputedStyle(document.body).direction === 'rtl';

const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;

Expand All @@ -112,38 +114,52 @@ export const calculatePosition = (
let x: number;
let y: number;

let leftBound = SAFE_AREA;
let rightBound = windowWidth - effectiveWidth - SAFE_AREA;
let topBound = SAFE_AREA;
let bottomBound = windowHeight - effectiveHeight - SAFE_AREA;

switch (corner) {
case 'top-right':
x = windowWidth - effectiveWidth - SAFE_AREA;
y = SAFE_AREA;
x = isRTL ? -leftBound : rightBound;
y = topBound;
break;
case 'bottom-right':
x = windowWidth - effectiveWidth - SAFE_AREA;
y = windowHeight - effectiveHeight - SAFE_AREA;
x = isRTL ? -leftBound : rightBound;
y = bottomBound;
break;
case 'bottom-left':
x = SAFE_AREA;
y = windowHeight - effectiveHeight - SAFE_AREA;
x = isRTL ? -rightBound : leftBound;
y = bottomBound;
break;
case 'top-left':
x = SAFE_AREA;
y = SAFE_AREA;
x = isRTL ? -rightBound : leftBound;
y = topBound;
break;
default:
x = SAFE_AREA;
y = SAFE_AREA;
x = leftBound;
y = topBound;
break;
}

// Only ensure positions are within bounds if minimized
if (isMinimized) {
x = Math.max(
SAFE_AREA,
Math.min(x, windowWidth - effectiveWidth - SAFE_AREA),
);
if (isRTL) {
// For RTL
x = Math.min(
-leftBound,
Math.max(x, -rightBound)
);
} else {
// For LTR
x = Math.max(
leftBound,
Math.min(x, rightBound),
);
}
y = Math.max(
SAFE_AREA,
Math.min(y, windowHeight - effectiveHeight - SAFE_AREA),
topBound,
Math.min(y, bottomBound),
);
}

Expand Down Expand Up @@ -207,6 +223,8 @@ export const calculateNewSizeAndPosition = (
deltaX: number,
deltaY: number,
): { newSize: Size; newPosition: Position } => {
const isRTL = getComputedStyle(document.body).direction === 'rtl';

const maxWidth = window.innerWidth - SAFE_AREA * 2;
const maxHeight = window.innerHeight - SAFE_AREA * 2;

Expand All @@ -215,14 +233,28 @@ export const calculateNewSizeAndPosition = (
let newX = initialPosition.x;
let newY = initialPosition.y;

// horizontal resize
if (position.includes('right')) {
// horizontal resize for RTL
if (isRTL && position.includes('right')) {
// Check if we have enough space on the right
const availableWidth = -initialPosition.x + initialSize.width - SAFE_AREA;
const proposedWidth = Math.min(initialSize.width + deltaX, availableWidth);
newWidth = Math.min(maxWidth, Math.max(MIN_SIZE.width, proposedWidth));
newX = initialPosition.x + (newWidth - initialSize.width);
}
if (isRTL && position.includes('left')) {
// Check if we have enough space on the left
const availableWidth = window.innerWidth - initialPosition.x - SAFE_AREA;
const proposedWidth = Math.min(initialSize.width - deltaX, availableWidth);
newWidth = Math.min(maxWidth, Math.max(MIN_SIZE.width, proposedWidth));
}
// horizontal resize for LTR
if (!isRTL && position.includes('right')) {
// Check if we have enough space on the right
const availableWidth = window.innerWidth - initialPosition.x - SAFE_AREA;
const proposedWidth = Math.min(initialSize.width + deltaX, availableWidth);
newWidth = Math.min(maxWidth, Math.max(MIN_SIZE.width, proposedWidth));
}
if (position.includes('left')) {
if (!isRTL && position.includes('left')) {
// Check if we have enough space on the left
const availableWidth = initialPosition.x + initialSize.width - SAFE_AREA;
const proposedWidth = Math.min(initialSize.width - deltaX, availableWidth);
Expand Down Expand Up @@ -257,14 +289,29 @@ export const calculateNewSizeAndPosition = (
newY = initialPosition.y - (newHeight - initialSize.height);
}

let leftBound = SAFE_AREA;
let rightBound = window.innerWidth - SAFE_AREA - newWidth;
let topBound = SAFE_AREA;
let bottomBound = window.innerHeight - SAFE_AREA - newHeight;

// Ensure position stays within bounds
newX = Math.max(
SAFE_AREA,
Math.min(newX, window.innerWidth - SAFE_AREA - newWidth),
);
if (isRTL) {
// for RTL
newX = Math.min(
-leftBound,
Math.max(newX, -rightBound)
);
} else {
// for LTR
newX = Math.max(
leftBound,
Math.min(newX, rightBound),
);
}

newY = Math.max(
SAFE_AREA,
Math.min(newY, window.innerHeight - SAFE_AREA - newHeight),
topBound,
Math.min(newY, bottomBound),
);

return {
Expand Down