Skip to content

Commit 68daa99

Browse files
committed
[newswires] ensure 'add selection' buttons don't ever burst out of container, by detecting left vs right and shifting the position accordingly
1 parent dca4c43 commit 68daa99

File tree

2 files changed

+60
-44
lines changed

2 files changed

+60
-44
lines changed

bootstrapping-lambda/local/index.html

+28-26
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,6 @@
77
</head>
88

99
<body>
10-
<hr />
11-
<p>not inside target</p>
12-
<h2>Not inside target</h2>
13-
<div
14-
data-pinboard-selection-target
15-
style="padding: 20px; background-color: aliceblue"
16-
>
17-
<h3>Pinboard selection target</h3>
18-
<p>
19-
This is a target for the Pinboard library to render the selection
20-
interface into. It will be hidden by the library when not in use. This
21-
is a target for the Pinboard library to render the selection interface
22-
into. It will be hidden by the library when not in use. This is a target
23-
for the Pinboard library to render the selection interface into. It will
24-
be hidden by the library when not in use. This is a target for the
25-
Pinboard library to render the selection interface into. It will be
26-
hidden by the library when not in use. This is a target for the Pinboard
27-
library to render the selection interface into. It will be hidden by the
28-
library when not in use. This is a target for the Pinboard library to
29-
render the selection interface into. It will be hidden by the library
30-
when not in use.
31-
</p>
32-
</div>
33-
<p>not inside target</p>
34-
35-
<hr />
3610
<a href="?expandPinboard=true"
3711
>Expand pinboard via query param <code>?expandPinboard=true</code></a
3812
>
@@ -127,6 +101,34 @@ <h4>presented after 1 second</h4>
127101
and Pinboard detecting that and still taking over the element
128102
</p>
129103
</ul>
104+
<div style="padding: 20px; background-color: aliceblue">
105+
<h3>Pinboard selection target</h3>
106+
<div
107+
data-pinboard-selection-target
108+
data-usage-note="This is a sample usage note, copyright Pinboard sandbox."
109+
>
110+
<p>
111+
This is a target for the <strong>Pinboard</strong> library to render
112+
the selection interface into. It will be hidden by the library when
113+
not in use. This is a target for the <em>Pinboard</em> library to
114+
render the selection interface into. It will be hidden by the library
115+
when not in use. This is a target for the
116+
<strong>Pinboard</strong> library to render the selection interface
117+
into. It will be hidden by the library when not in use.
118+
</p>
119+
<p>
120+
This is a target for the <em>Pinboard</em> library to render the
121+
selection interface into. It will be hidden by the library when not in
122+
use. This is a target for the <strong>Pinboard</strong> library to
123+
render the selection interface into. It will be hidden by the library
124+
when not in use. This is a target for the <em>Pinboard</em> library to
125+
render the selection interface into. It will be hidden by the library
126+
when not in use.
127+
</p>
128+
</div>
129+
</div>
130+
131+
<hr />
130132
</body>
131133
<script>
132134
setTimeout(

client/src/newswires/newswiresIntegration.tsx

+32-18
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const SELECTION_TARGET_DATA_ATTR = "[data-pinboard-selection-target]";
1616
interface ButtonPosition {
1717
top: number;
1818
left: number;
19+
unRoundedCorner: "bottom-left" | "top-right" | "top-left" | "bottom-right";
1920
}
2021

2122
export const NewswiresIntegration = () => {
@@ -49,14 +50,27 @@ export const NewswiresIntegration = () => {
4950
);
5051
const firstRect = selectionRects[0];
5152
const lastRect = selectionRects[selectionRects.length - 1];
52-
const newFirstButtonCoords = {
53+
const firstButtonCoords = {
5354
top: firstRect.y - parentRect.y,
5455
left: firstRect.x - parentRect.x,
5556
};
56-
const newLastButtonCoords = {
57+
const firstButtonPosition: ButtonPosition = {
58+
...firstButtonCoords,
59+
unRoundedCorner: `bottom-${
60+
firstButtonCoords.left > parentRect.width / 2 ? "right" : "left"
61+
}`,
62+
};
63+
const lastButtonCoords = {
5764
top: lastRect.y - parentRect.y + lastRect.height,
5865
left: lastRect.x - parentRect.x + lastRect.width - 1,
5966
};
67+
const lastButtonPosition: ButtonPosition = {
68+
...lastButtonCoords,
69+
unRoundedCorner: `top-${
70+
lastButtonCoords.left > parentRect.width / 2 ? "right" : "left"
71+
}`,
72+
};
73+
6074
if (maybeClonedTargetEl) {
6175
console.log(
6276
"selection contains whole target element; contents:",
@@ -65,8 +79,8 @@ export const NewswiresIntegration = () => {
6579
setState({
6680
selectedHTML: maybeClonedTargetEl.innerHTML,
6781
containerElement: maybeOriginalTargetEl,
68-
firstButtonPosition: newFirstButtonCoords,
69-
lastButtonPosition: newLastButtonCoords,
82+
firstButtonPosition,
83+
lastButtonPosition,
7084
});
7185
} else if (
7286
maybeOriginalTargetEl?.contains(selection.anchorNode) &&
@@ -81,10 +95,10 @@ export const NewswiresIntegration = () => {
8195
setState({
8296
selectedHTML: tempEl.innerHTML,
8397
containerElement: maybeOriginalTargetEl,
84-
firstButtonPosition: newFirstButtonCoords,
85-
lastButtonPosition: newLastButtonCoords,
98+
firstButtonPosition,
99+
lastButtonPosition,
86100
});
87-
//TODO might need to clean up tempEl
101+
//TODO might need to clean up tempEl to avoid memory leak?
88102
}
89103
}
90104
};
@@ -107,8 +121,8 @@ export const NewswiresIntegration = () => {
107121
* [x] check parent node of selection is newswires body text el (maybe add data attribute to body text el)
108122
* - (find first shared parent of anchorNode and focusNode, make sure we're not sharing bits of text outside of the target)
109123
* [x] extract HTML from selection (see chat thread)
110-
* [ ] render button when there's a selection
111-
* [ ] do things with pinboard
124+
* [x] render button when there's a selection
125+
* [x] do things with pinboard
112126
*/
113127
return () =>
114128
document.removeEventListener(
@@ -157,10 +171,14 @@ export const NewswiresIntegration = () => {
157171
left: ${buttonCoords.left}px;
158172
transform: translate(
159173
${
160-
buttonCoords === state.firstButtonPosition
161-
? "0, -100%"
162-
: "-100%, 0"
163-
}
174+
buttonCoords.unRoundedCorner.includes("left")
175+
? "0"
176+
: "-100%"
177+
},${
178+
buttonCoords.unRoundedCorner.includes("bottom")
179+
? "-100%"
180+
: "0"
181+
}
164182
);
165183
display: flex;
166184
align-items: center;
@@ -169,11 +187,7 @@ export const NewswiresIntegration = () => {
169187
box-shadow: ${boxShadow};
170188
border: none;
171189
border-radius: 100px;
172-
border-${
173-
buttonCoords === state.firstButtonPosition
174-
? "bottom-left"
175-
: "top-right"
176-
}-radius: 0;
190+
border-${buttonCoords.unRoundedCorner}-radius: 0;
177191
padding: 0 ${space[2]}px 0 ${space[3]}px;
178192
line-height: 2;
179193
cursor: pointer;

0 commit comments

Comments
 (0)