Skip to content

Commit 8024ce7

Browse files
authored
fix(desktop): mask composer rounded corners (#2165)
1 parent 4fe3835 commit 8024ce7

4 files changed

Lines changed: 75 additions & 3 deletions

File tree

‎desktop/src/features/channels/ui/ChannelPane.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ export const ChannelPane = React.memo(function ChannelPane({
734734
data-testid="channel-composer-overlay"
735735
ref={composerWrapperRef}
736736
>
737-
<div className="pointer-events-auto">
737+
<div className="composer-overlay-corner-masks pointer-events-auto">
738738
{timeoutState.active ? (
739739
<ComposerTimeoutBanner
740740
expiresAtMs={timeoutState.expiresAtMs}

‎desktop/src/features/messages/ui/MessageThreadPanel.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ export function MessageThreadPanel({
816816
>
817817
<div
818818
className={cn(
819-
"pointer-events-auto",
819+
"composer-overlay-corner-masks pointer-events-auto",
820820
hasConstrainedColumn && THREAD_PANEL_COLUMN_CLASS,
821821
)}
822822
style={

‎desktop/src/shared/styles/globals/composer.css‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
.composer-overlay-corner-masks::before,
2+
.composer-overlay-corner-masks::after {
3+
position: absolute;
4+
bottom: 2.5rem;
5+
z-index: 0;
6+
width: 1rem;
7+
height: 1rem;
8+
background: hsl(var(--background));
9+
content: "";
10+
}
11+
12+
.composer-overlay-corner-masks::before {
13+
left: 1.25rem;
14+
mask-image: radial-gradient(
15+
circle at top right,
16+
transparent 0 1rem,
17+
black calc(1rem + 0.5px)
18+
);
19+
-webkit-mask-image: radial-gradient(
20+
circle at top right,
21+
transparent 0 1rem,
22+
black calc(1rem + 0.5px)
23+
);
24+
}
25+
26+
.composer-overlay-corner-masks::after {
27+
right: 1.25rem;
28+
mask-image: radial-gradient(
29+
circle at top left,
30+
transparent 0 1rem,
31+
black calc(1rem + 0.5px)
32+
);
33+
-webkit-mask-image: radial-gradient(
34+
circle at top left,
35+
transparent 0 1rem,
36+
black calc(1rem + 0.5px)
37+
);
38+
}
39+
140
.rich-text-composer .tiptap {
241
outline: none;
342
min-height: 1lh;

‎desktop/tests/e2e/channel-composer-overflow.spec.ts‎

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,40 @@ async function expectOverlayBottomMask(
5252
const hasMask = await overlay.evaluate((element) => {
5353
const after = getComputedStyle(element, "::after");
5454
const before = getComputedStyle(element, "::before");
55-
return after.content !== "none" && before.content !== "none";
55+
const composer = element.querySelector<HTMLElement>(
56+
'[data-testid="message-composer"]',
57+
);
58+
const cornerMaskContainer = element.querySelector<HTMLElement>(
59+
".composer-overlay-corner-masks",
60+
);
61+
if (!composer || !cornerMaskContainer) return false;
62+
63+
const overlayRect = element.getBoundingClientRect();
64+
const composerRect = composer.getBoundingClientRect();
65+
const leftMask = getComputedStyle(cornerMaskContainer, "::before");
66+
const rightMask = getComputedStyle(cornerMaskContainer, "::after");
67+
const tolerance = 0.5;
68+
69+
return (
70+
after.content !== "none" &&
71+
before.content !== "none" &&
72+
leftMask.maskImage !== "none" &&
73+
rightMask.maskImage !== "none" &&
74+
Math.abs(
75+
composerRect.left - overlayRect.left - Number.parseFloat(leftMask.left),
76+
) <= tolerance &&
77+
Math.abs(
78+
overlayRect.right -
79+
composerRect.right -
80+
Number.parseFloat(rightMask.right),
81+
) <= tolerance &&
82+
Math.abs(
83+
overlayRect.bottom -
84+
composerRect.bottom -
85+
Number.parseFloat(leftMask.bottom),
86+
) <= tolerance &&
87+
leftMask.bottom === rightMask.bottom
88+
);
5689
});
5790
expect(hasMask).toBe(true);
5891
}

0 commit comments

Comments
 (0)