react-grab 0.0.21 → 0.0.23
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.cjs +835 -498
- package/dist/index.global.js +28 -66
- package/dist/index.js +835 -498
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var web = require('solid-js/web');
|
|
4
|
+
var solidJs = require('solid-js');
|
|
3
5
|
var bippy = require('bippy');
|
|
4
6
|
var source = require('bippy/dist/source');
|
|
5
7
|
|
|
@@ -12,6 +14,7 @@ var source = require('bippy/dist/source');
|
|
|
12
14
|
* LICENSE file in the root directory of this source tree.
|
|
13
15
|
*/
|
|
14
16
|
|
|
17
|
+
|
|
15
18
|
// src/utils/is-keyboard-event-triggered-by-input.ts
|
|
16
19
|
var FORM_TAGS_AND_ROLES = [
|
|
17
20
|
"input",
|
|
@@ -92,348 +95,433 @@ var mountRoot = () => {
|
|
|
92
95
|
var isElementVisible = (element, computedStyle = window.getComputedStyle(element)) => {
|
|
93
96
|
return computedStyle.display !== "none" && computedStyle.visibility !== "hidden" && computedStyle.opacity !== "0";
|
|
94
97
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
var
|
|
98
|
-
var
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!template) {
|
|
102
|
-
template = document.createElement("template");
|
|
103
|
-
template.innerHTML = strings.reduce((acc, str, i) => acc + str + (values[i] ?? ""), "");
|
|
104
|
-
templateCache.set(key, template);
|
|
105
|
-
}
|
|
106
|
-
return template.content.firstElementChild.cloneNode(true);
|
|
107
|
-
};
|
|
98
|
+
var _tmpl$ = /* @__PURE__ */ web.template(`<div>`);
|
|
99
|
+
var _tmpl$2 = /* @__PURE__ */ web.template(`<span style="display:inline-block;width:8px;height:8px;border:1.5px solid rgb(210, 57, 192);border-top-color:transparent;border-radius:50%;margin-right:4px;vertical-align:middle">`);
|
|
100
|
+
var _tmpl$3 = /* @__PURE__ */ web.template(`<span style=display:inline-block;margin-right:4px;font-weight:600>\u2713`);
|
|
101
|
+
var _tmpl$4 = /* @__PURE__ */ web.template(`<span style="font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;font-variant-numeric:tabular-nums">`);
|
|
102
|
+
var _tmpl$5 = /* @__PURE__ */ web.template(`<div style="position:fixed;padding:2px 6px;background-color:#fde7f7;color:#b21c8e;border:1px solid #f7c5ec;border-radius:4px;font-size:11px;font-weight:500;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;pointer-events:none;transition:opacity 0.2s ease-in-out;display:flex;align-items:center;max-width:calc(100vw - (16px + env(safe-area-inset-left) + env(safe-area-inset-right)));overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><span>`);
|
|
103
|
+
var _tmpl$6 = /* @__PURE__ */ web.template(`<div style="position:fixed;z-index:2147483647;pointer-events:none;transition:opacity 0.1s ease-in-out"><div style="width:32px;height:2px;background-color:rgba(178, 28, 142, 0.2);border-radius:1px;overflow:hidden;position:relative"><div style="height:100%;background-color:#b21c8e;border-radius:1px;transition:width 0.05s cubic-bezier(0.165, 0.84, 0.44, 1)">`);
|
|
108
104
|
var VIEWPORT_MARGIN_PX = 8;
|
|
109
105
|
var LABEL_OFFSET_PX = 6;
|
|
110
106
|
var INDICATOR_CLAMP_PADDING_PX = 4;
|
|
111
107
|
var INDICATOR_SUCCESS_VISIBLE_MS = 1500;
|
|
112
|
-
var
|
|
108
|
+
var SELECTION_LERP_FACTOR = 0.95;
|
|
109
|
+
var MARQUEE_LERP_FACTOR = 0.9;
|
|
113
110
|
var lerp = (start, end, factor) => {
|
|
114
111
|
return start + (end - start) * factor;
|
|
115
112
|
};
|
|
116
|
-
var
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
x,
|
|
123
|
-
y
|
|
124
|
-
}) => {
|
|
125
|
-
const overlay = html`
|
|
126
|
-
<div style="
|
|
127
|
-
position: fixed;
|
|
128
|
-
top: ${y}px;
|
|
129
|
-
left: ${x}px;
|
|
130
|
-
width: ${width}px;
|
|
131
|
-
height: ${height}px;
|
|
132
|
-
border-radius: ${borderRadius};
|
|
133
|
-
transform: ${transform};
|
|
134
|
-
pointer-events: auto;
|
|
135
|
-
border: 1px solid rgb(210, 57, 192);
|
|
136
|
-
background-color: rgba(210, 57, 192, 0.2);
|
|
137
|
-
z-index: 2147483646;
|
|
138
|
-
box-sizing: border-box;
|
|
139
|
-
display: none;
|
|
140
|
-
"></div>
|
|
141
|
-
`;
|
|
142
|
-
return overlay;
|
|
143
|
-
};
|
|
144
|
-
var updateSelectionElement = (element, { borderRadius, height, transform, width, x, y }) => {
|
|
145
|
-
const currentTop = parseFloat(element.style.top) || 0;
|
|
146
|
-
const currentLeft = parseFloat(element.style.left) || 0;
|
|
147
|
-
const currentWidth = parseFloat(element.style.width) || 0;
|
|
148
|
-
const currentHeight = parseFloat(element.style.height) || 0;
|
|
149
|
-
const topValue = `${lerp(currentTop, y, SELECTION_LERP_FACTOR)}px`;
|
|
150
|
-
const leftValue = `${lerp(currentLeft, x, SELECTION_LERP_FACTOR)}px`;
|
|
151
|
-
const widthValue = `${lerp(currentWidth, width, SELECTION_LERP_FACTOR)}px`;
|
|
152
|
-
const heightValue = `${lerp(currentHeight, height, SELECTION_LERP_FACTOR)}px`;
|
|
153
|
-
if (element.style.top !== topValue) {
|
|
154
|
-
element.style.top = topValue;
|
|
155
|
-
}
|
|
156
|
-
if (element.style.left !== leftValue) {
|
|
157
|
-
element.style.left = leftValue;
|
|
158
|
-
}
|
|
159
|
-
if (element.style.width !== widthValue) {
|
|
160
|
-
element.style.width = widthValue;
|
|
161
|
-
}
|
|
162
|
-
if (element.style.height !== heightValue) {
|
|
163
|
-
element.style.height = heightValue;
|
|
164
|
-
}
|
|
165
|
-
if (element.style.borderRadius !== borderRadius) {
|
|
166
|
-
element.style.borderRadius = borderRadius;
|
|
167
|
-
}
|
|
168
|
-
if (element.style.transform !== transform) {
|
|
169
|
-
element.style.transform = transform;
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
var createSelectionOverlay = (root, onSelectionClick) => {
|
|
173
|
-
const element = createSelectionElement({
|
|
174
|
-
borderRadius: "0px",
|
|
175
|
-
height: 0,
|
|
176
|
-
transform: "none",
|
|
177
|
-
width: 0,
|
|
178
|
-
x: -1e3,
|
|
179
|
-
y: -1e3
|
|
180
|
-
});
|
|
181
|
-
root.appendChild(element);
|
|
182
|
-
let visible = false;
|
|
113
|
+
var Overlay = (props) => {
|
|
114
|
+
const [currentX, setCurrentX] = solidJs.createSignal(props.bounds.x);
|
|
115
|
+
const [currentY, setCurrentY] = solidJs.createSignal(props.bounds.y);
|
|
116
|
+
const [currentWidth, setCurrentWidth] = solidJs.createSignal(props.bounds.width);
|
|
117
|
+
const [currentHeight, setCurrentHeight] = solidJs.createSignal(props.bounds.height);
|
|
118
|
+
const [opacity, setOpacity] = solidJs.createSignal(1);
|
|
183
119
|
let hasBeenShown = false;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
element.style.top = `${selection.y}px`;
|
|
211
|
-
element.style.left = `${selection.x}px`;
|
|
212
|
-
element.style.width = `${selection.width}px`;
|
|
213
|
-
element.style.height = `${selection.height}px`;
|
|
214
|
-
element.style.borderRadius = selection.borderRadius;
|
|
215
|
-
element.style.transform = selection.transform;
|
|
216
|
-
hasBeenShown = true;
|
|
120
|
+
let animationFrameId = null;
|
|
121
|
+
let targetBounds = props.bounds;
|
|
122
|
+
solidJs.createEffect(() => {
|
|
123
|
+
targetBounds = props.bounds;
|
|
124
|
+
const factor = props.lerpFactor ?? SELECTION_LERP_FACTOR;
|
|
125
|
+
if (!hasBeenShown) {
|
|
126
|
+
setCurrentX(targetBounds.x);
|
|
127
|
+
setCurrentY(targetBounds.y);
|
|
128
|
+
setCurrentWidth(targetBounds.width);
|
|
129
|
+
setCurrentHeight(targetBounds.height);
|
|
130
|
+
hasBeenShown = true;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const EPSILON = 0.5;
|
|
134
|
+
const animate = () => {
|
|
135
|
+
const newX = lerp(currentX(), targetBounds.x, factor);
|
|
136
|
+
const newY = lerp(currentY(), targetBounds.y, factor);
|
|
137
|
+
const newWidth = lerp(currentWidth(), targetBounds.width, factor);
|
|
138
|
+
const newHeight = lerp(currentHeight(), targetBounds.height, factor);
|
|
139
|
+
setCurrentX(newX);
|
|
140
|
+
setCurrentY(newY);
|
|
141
|
+
setCurrentWidth(newWidth);
|
|
142
|
+
setCurrentHeight(newHeight);
|
|
143
|
+
const hasConverged = Math.abs(newX - targetBounds.x) < EPSILON && Math.abs(newY - targetBounds.y) < EPSILON && Math.abs(newWidth - targetBounds.width) < EPSILON && Math.abs(newHeight - targetBounds.height) < EPSILON;
|
|
144
|
+
if (!hasConverged) {
|
|
145
|
+
animationFrameId = requestAnimationFrame(animate);
|
|
217
146
|
} else {
|
|
218
|
-
|
|
147
|
+
animationFrameId = null;
|
|
219
148
|
}
|
|
149
|
+
};
|
|
150
|
+
if (animationFrameId !== null) {
|
|
151
|
+
cancelAnimationFrame(animationFrameId);
|
|
152
|
+
}
|
|
153
|
+
animationFrameId = requestAnimationFrame(animate);
|
|
154
|
+
solidJs.onCleanup(() => {
|
|
155
|
+
if (animationFrameId !== null) {
|
|
156
|
+
cancelAnimationFrame(animationFrameId);
|
|
157
|
+
animationFrameId = null;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
solidJs.createEffect(() => {
|
|
162
|
+
if (props.variant === "grabbed") {
|
|
163
|
+
requestAnimationFrame(() => {
|
|
164
|
+
setOpacity(0);
|
|
165
|
+
});
|
|
220
166
|
}
|
|
167
|
+
});
|
|
168
|
+
const baseStyle = {
|
|
169
|
+
position: "fixed",
|
|
170
|
+
"box-sizing": "border-box",
|
|
171
|
+
"pointer-events": props.variant === "marquee" ? "none" : "auto",
|
|
172
|
+
"z-index": "2147483646"
|
|
221
173
|
};
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
174
|
+
const variantStyle = () => {
|
|
175
|
+
if (props.variant === "marquee") {
|
|
176
|
+
return {
|
|
177
|
+
border: "1px dashed rgb(210, 57, 192)",
|
|
178
|
+
"background-color": "rgba(210, 57, 192, 0.1)",
|
|
179
|
+
"will-change": "transform, width, height",
|
|
180
|
+
contain: "layout paint size"
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
border: "1px solid rgb(210, 57, 192)",
|
|
185
|
+
"background-color": "rgba(210, 57, 192, 0.2)",
|
|
186
|
+
transition: props.variant === "grabbed" ? "opacity 0.3s ease-out" : void 0
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
return web.createComponent(solidJs.Show, {
|
|
190
|
+
get when() {
|
|
191
|
+
return props.visible !== false;
|
|
192
|
+
},
|
|
193
|
+
get children() {
|
|
194
|
+
var _el$ = _tmpl$();
|
|
195
|
+
web.effect((_$p) => web.style(_el$, {
|
|
196
|
+
...baseStyle,
|
|
197
|
+
...variantStyle(),
|
|
198
|
+
top: `${currentY()}px`,
|
|
199
|
+
left: `${currentX()}px`,
|
|
200
|
+
width: `${currentWidth()}px`,
|
|
201
|
+
height: `${currentHeight()}px`,
|
|
202
|
+
"border-radius": props.bounds.borderRadius,
|
|
203
|
+
transform: props.bounds.transform,
|
|
204
|
+
opacity: opacity()
|
|
205
|
+
}, _$p));
|
|
206
|
+
return _el$;
|
|
207
|
+
}
|
|
242
208
|
});
|
|
243
|
-
setTimeout(() => {
|
|
244
|
-
element.remove();
|
|
245
|
-
}, 300);
|
|
246
209
|
};
|
|
247
|
-
var
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
spinner.animate(
|
|
261
|
-
[{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }],
|
|
262
|
-
{
|
|
263
|
-
duration: 600,
|
|
264
|
-
easing: "linear",
|
|
265
|
-
iterations: Infinity
|
|
210
|
+
var Spinner = (props) => {
|
|
211
|
+
let ref;
|
|
212
|
+
solidJs.createEffect(() => {
|
|
213
|
+
if (ref) {
|
|
214
|
+
ref.animate([{
|
|
215
|
+
transform: "rotate(0deg)"
|
|
216
|
+
}, {
|
|
217
|
+
transform: "rotate(360deg)"
|
|
218
|
+
}], {
|
|
219
|
+
duration: 600,
|
|
220
|
+
easing: "linear",
|
|
221
|
+
iterations: Infinity
|
|
222
|
+
});
|
|
266
223
|
}
|
|
267
|
-
);
|
|
268
|
-
return
|
|
269
|
-
|
|
270
|
-
var
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
background-color: #fde7f7;
|
|
278
|
-
color: #b21c8e;
|
|
279
|
-
border: 1px solid #f7c5ec;
|
|
280
|
-
border-radius: 4px;
|
|
281
|
-
font-size: 11px;
|
|
282
|
-
font-weight: 500;
|
|
283
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
284
|
-
z-index: 2147483647;
|
|
285
|
-
pointer-events: none;
|
|
286
|
-
opacity: 0;
|
|
287
|
-
transition: opacity 0.2s ease-in-out;
|
|
288
|
-
display: flex;
|
|
289
|
-
align-items: center;
|
|
290
|
-
max-width: calc(100vw - (16px + env(safe-area-inset-left) + env(safe-area-inset-right)));
|
|
291
|
-
overflow: hidden;
|
|
292
|
-
text-overflow: ellipsis;
|
|
293
|
-
white-space: nowrap;
|
|
294
|
-
"></div>
|
|
295
|
-
`;
|
|
296
|
-
return indicator;
|
|
224
|
+
});
|
|
225
|
+
return (() => {
|
|
226
|
+
var _el$2 = _tmpl$2();
|
|
227
|
+
var _ref$ = ref;
|
|
228
|
+
typeof _ref$ === "function" ? web.use(_ref$, _el$2) : ref = _el$2;
|
|
229
|
+
web.effect((_$p) => web.style(_el$2, {
|
|
230
|
+
...props.style
|
|
231
|
+
}, _$p));
|
|
232
|
+
return _el$2;
|
|
233
|
+
})();
|
|
297
234
|
};
|
|
298
|
-
var
|
|
299
|
-
|
|
300
|
-
let
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
isProcessing = false;
|
|
307
|
-
}
|
|
308
|
-
if (!isProcessing) {
|
|
309
|
-
const labelText = indicator.querySelector("span");
|
|
310
|
-
if (labelText) {
|
|
311
|
-
const tagNameMonospace = document.createElement("span");
|
|
312
|
-
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
313
|
-
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
314
|
-
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
315
|
-
labelText.replaceChildren(tagNameMonospace);
|
|
235
|
+
var Label = (props) => {
|
|
236
|
+
const [opacity, setOpacity] = solidJs.createSignal(0);
|
|
237
|
+
let ref;
|
|
238
|
+
solidJs.createEffect(() => {
|
|
239
|
+
if (props.visible !== false) {
|
|
240
|
+
requestAnimationFrame(() => {
|
|
241
|
+
setOpacity(1);
|
|
242
|
+
});
|
|
316
243
|
} else {
|
|
317
|
-
|
|
318
|
-
const tagNameMonospace = document.createElement("span");
|
|
319
|
-
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
320
|
-
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
321
|
-
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
322
|
-
newLabelText.appendChild(tagNameMonospace);
|
|
323
|
-
indicator.appendChild(newLabelText);
|
|
244
|
+
setOpacity(0);
|
|
324
245
|
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const
|
|
335
|
-
const
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if (isClamped) {
|
|
342
|
-
indicatorLeftPx += CLAMPED_PADDING;
|
|
343
|
-
indicatorTopPx += CLAMPED_PADDING;
|
|
344
|
-
}
|
|
345
|
-
indicator.style.left = `${indicatorLeftPx}px`;
|
|
346
|
-
indicator.style.top = `${indicatorTopPx}px`;
|
|
347
|
-
indicator.style.right = "auto";
|
|
348
|
-
if (isNewIndicator) {
|
|
349
|
-
requestAnimationFrame(() => {
|
|
350
|
-
indicator.style.opacity = "1";
|
|
351
|
-
});
|
|
352
|
-
} else if (indicator.style.opacity !== "1") {
|
|
353
|
-
indicator.style.opacity = "1";
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
var isProcessing = false;
|
|
357
|
-
var activeGrabbedIndicators = /* @__PURE__ */ new Set();
|
|
358
|
-
var updateLabelToProcessing = (root, selectionLeftPx, selectionTopPx) => {
|
|
359
|
-
const indicator = createIndicator();
|
|
360
|
-
indicator.style.zIndex = "2147483648";
|
|
361
|
-
root.appendChild(indicator);
|
|
362
|
-
activeGrabbedIndicators.add(indicator);
|
|
363
|
-
const positionIndicator = () => {
|
|
364
|
-
if (selectionLeftPx === void 0 || selectionTopPx === void 0) return;
|
|
365
|
-
const indicatorRect = indicator.getBoundingClientRect();
|
|
246
|
+
});
|
|
247
|
+
solidJs.createEffect(() => {
|
|
248
|
+
if (props.variant === "success") {
|
|
249
|
+
const fadeOutTimer = setTimeout(() => {
|
|
250
|
+
setOpacity(0);
|
|
251
|
+
}, INDICATOR_SUCCESS_VISIBLE_MS);
|
|
252
|
+
solidJs.onCleanup(() => clearTimeout(fadeOutTimer));
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
const indicatorRect = () => ref?.getBoundingClientRect();
|
|
256
|
+
const computedPosition = () => {
|
|
257
|
+
const rect = indicatorRect();
|
|
258
|
+
if (!rect) return {
|
|
259
|
+
left: props.x,
|
|
260
|
+
top: props.y
|
|
261
|
+
};
|
|
366
262
|
const viewportWidthPx = window.innerWidth;
|
|
367
263
|
const viewportHeightPx = window.innerHeight;
|
|
368
|
-
let indicatorLeftPx = Math.round(
|
|
369
|
-
let indicatorTopPx = Math.round(
|
|
370
|
-
const CLAMPED_PADDING = INDICATOR_CLAMP_PADDING_PX;
|
|
264
|
+
let indicatorLeftPx = Math.round(props.x);
|
|
265
|
+
let indicatorTopPx = Math.round(props.y) - rect.height - LABEL_OFFSET_PX;
|
|
371
266
|
const minLeft = VIEWPORT_MARGIN_PX;
|
|
372
267
|
const minTop = VIEWPORT_MARGIN_PX;
|
|
373
|
-
const maxLeft = viewportWidthPx -
|
|
374
|
-
const maxTop = viewportHeightPx -
|
|
268
|
+
const maxLeft = viewportWidthPx - rect.width - VIEWPORT_MARGIN_PX;
|
|
269
|
+
const maxTop = viewportHeightPx - rect.height - VIEWPORT_MARGIN_PX;
|
|
375
270
|
const willClampLeft = indicatorLeftPx < minLeft;
|
|
376
271
|
const willClampTop = indicatorTopPx < minTop;
|
|
377
272
|
const isClamped = willClampLeft || willClampTop;
|
|
378
273
|
indicatorLeftPx = Math.max(minLeft, Math.min(indicatorLeftPx, maxLeft));
|
|
379
274
|
indicatorTopPx = Math.max(minTop, Math.min(indicatorTopPx, maxTop));
|
|
380
275
|
if (isClamped) {
|
|
381
|
-
indicatorLeftPx +=
|
|
382
|
-
indicatorTopPx +=
|
|
276
|
+
indicatorLeftPx += INDICATOR_CLAMP_PADDING_PX;
|
|
277
|
+
indicatorTopPx += INDICATOR_CLAMP_PADDING_PX;
|
|
383
278
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
279
|
+
return {
|
|
280
|
+
left: indicatorLeftPx,
|
|
281
|
+
top: indicatorTopPx
|
|
282
|
+
};
|
|
387
283
|
};
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
284
|
+
return web.createComponent(solidJs.Show, {
|
|
285
|
+
get when() {
|
|
286
|
+
return props.visible !== false;
|
|
287
|
+
},
|
|
288
|
+
get children() {
|
|
289
|
+
var _el$3 = _tmpl$5(), _el$5 = _el$3.firstChild;
|
|
290
|
+
var _ref$2 = ref;
|
|
291
|
+
typeof _ref$2 === "function" ? web.use(_ref$2, _el$3) : ref = _el$3;
|
|
292
|
+
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
293
|
+
get when() {
|
|
294
|
+
return props.variant === "processing";
|
|
295
|
+
},
|
|
296
|
+
get children() {
|
|
297
|
+
return web.createComponent(Spinner, {});
|
|
298
|
+
}
|
|
299
|
+
}), _el$5);
|
|
300
|
+
web.insert(_el$3, web.createComponent(solidJs.Show, {
|
|
301
|
+
get when() {
|
|
302
|
+
return props.variant === "success";
|
|
303
|
+
},
|
|
304
|
+
get children() {
|
|
305
|
+
return _tmpl$3();
|
|
306
|
+
}
|
|
307
|
+
}), _el$5);
|
|
308
|
+
web.insert(_el$5, web.createComponent(solidJs.Show, {
|
|
309
|
+
get when() {
|
|
310
|
+
return props.variant === "success";
|
|
311
|
+
},
|
|
312
|
+
children: "Grabbed "
|
|
313
|
+
}), null);
|
|
314
|
+
web.insert(_el$5, web.createComponent(solidJs.Show, {
|
|
315
|
+
get when() {
|
|
316
|
+
return props.variant === "processing";
|
|
317
|
+
},
|
|
318
|
+
children: "Grabbing\u2026"
|
|
319
|
+
}), null);
|
|
320
|
+
web.insert(_el$5, web.createComponent(solidJs.Show, {
|
|
321
|
+
get when() {
|
|
322
|
+
return props.variant === "hover";
|
|
323
|
+
},
|
|
324
|
+
get children() {
|
|
325
|
+
var _el$6 = _tmpl$4();
|
|
326
|
+
web.insert(_el$6, () => props.text);
|
|
327
|
+
return _el$6;
|
|
328
|
+
}
|
|
329
|
+
}), null);
|
|
330
|
+
web.insert(_el$5, web.createComponent(solidJs.Show, {
|
|
331
|
+
get when() {
|
|
332
|
+
return props.variant !== "hover";
|
|
333
|
+
},
|
|
334
|
+
get children() {
|
|
335
|
+
var _el$7 = _tmpl$4();
|
|
336
|
+
web.insert(_el$7, () => props.text);
|
|
337
|
+
return _el$7;
|
|
338
|
+
}
|
|
339
|
+
}), null);
|
|
340
|
+
web.effect((_p$) => {
|
|
341
|
+
var _v$ = `${computedPosition().top}px`, _v$2 = `${computedPosition().left}px`, _v$3 = props.zIndex?.toString() ?? "2147483647", _v$4 = opacity();
|
|
342
|
+
_v$ !== _p$.e && web.setStyleProperty(_el$3, "top", _p$.e = _v$);
|
|
343
|
+
_v$2 !== _p$.t && web.setStyleProperty(_el$3, "left", _p$.t = _v$2);
|
|
344
|
+
_v$3 !== _p$.a && web.setStyleProperty(_el$3, "z-index", _p$.a = _v$3);
|
|
345
|
+
_v$4 !== _p$.o && web.setStyleProperty(_el$3, "opacity", _p$.o = _v$4);
|
|
346
|
+
return _p$;
|
|
347
|
+
}, {
|
|
348
|
+
e: void 0,
|
|
349
|
+
t: void 0,
|
|
350
|
+
a: void 0,
|
|
351
|
+
o: void 0
|
|
352
|
+
});
|
|
353
|
+
return _el$3;
|
|
354
|
+
}
|
|
396
355
|
});
|
|
397
|
-
return (tagName) => {
|
|
398
|
-
indicator.textContent = "";
|
|
399
|
-
const checkmarkIcon = document.createElement("span");
|
|
400
|
-
checkmarkIcon.textContent = "\u2713";
|
|
401
|
-
checkmarkIcon.style.display = "inline-block";
|
|
402
|
-
checkmarkIcon.style.marginRight = "4px";
|
|
403
|
-
checkmarkIcon.style.fontWeight = "600";
|
|
404
|
-
const newLabelText = document.createElement("span");
|
|
405
|
-
const tagNameMonospace = document.createElement("span");
|
|
406
|
-
tagNameMonospace.textContent = tagName ? `<${tagName}>` : "<element>";
|
|
407
|
-
tagNameMonospace.style.fontFamily = "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace";
|
|
408
|
-
tagNameMonospace.style.fontVariantNumeric = "tabular-nums";
|
|
409
|
-
newLabelText.appendChild(document.createTextNode("Grabbed "));
|
|
410
|
-
newLabelText.appendChild(tagNameMonospace);
|
|
411
|
-
indicator.appendChild(checkmarkIcon);
|
|
412
|
-
indicator.appendChild(newLabelText);
|
|
413
|
-
requestAnimationFrame(() => {
|
|
414
|
-
positionIndicator();
|
|
415
|
-
});
|
|
416
|
-
setTimeout(() => {
|
|
417
|
-
indicator.style.opacity = "0";
|
|
418
|
-
setTimeout(() => {
|
|
419
|
-
indicator.remove();
|
|
420
|
-
activeGrabbedIndicators.delete(indicator);
|
|
421
|
-
}, INDICATOR_FADE_MS);
|
|
422
|
-
}, INDICATOR_SUCCESS_VISIBLE_MS);
|
|
423
|
-
};
|
|
424
356
|
};
|
|
425
|
-
var
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
357
|
+
var ProgressIndicator = (props) => {
|
|
358
|
+
const [opacity, setOpacity] = solidJs.createSignal(0);
|
|
359
|
+
let ref;
|
|
360
|
+
solidJs.createEffect(() => {
|
|
361
|
+
if (props.visible !== false) {
|
|
362
|
+
requestAnimationFrame(() => {
|
|
363
|
+
setOpacity(1);
|
|
364
|
+
});
|
|
365
|
+
} else {
|
|
366
|
+
setOpacity(0);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
const computedPosition = () => {
|
|
370
|
+
const rect = ref?.getBoundingClientRect();
|
|
371
|
+
if (!rect) return {
|
|
372
|
+
left: props.mouseX,
|
|
373
|
+
top: props.mouseY
|
|
374
|
+
};
|
|
375
|
+
const viewportWidth = window.innerWidth;
|
|
376
|
+
const viewportHeight = window.innerHeight;
|
|
377
|
+
const CURSOR_OFFSET = 14;
|
|
378
|
+
const VIEWPORT_MARGIN = 8;
|
|
379
|
+
let indicatorLeft = props.mouseX - rect.width / 2;
|
|
380
|
+
let indicatorTop = props.mouseY + CURSOR_OFFSET;
|
|
381
|
+
if (indicatorTop + rect.height + VIEWPORT_MARGIN > viewportHeight) {
|
|
382
|
+
indicatorTop = props.mouseY - rect.height - CURSOR_OFFSET;
|
|
383
|
+
}
|
|
384
|
+
indicatorTop = Math.max(VIEWPORT_MARGIN, Math.min(indicatorTop, viewportHeight - rect.height - VIEWPORT_MARGIN));
|
|
385
|
+
indicatorLeft = Math.max(VIEWPORT_MARGIN, Math.min(indicatorLeft, viewportWidth - rect.width - VIEWPORT_MARGIN));
|
|
386
|
+
return {
|
|
387
|
+
left: indicatorLeft,
|
|
388
|
+
top: indicatorTop
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
return web.createComponent(solidJs.Show, {
|
|
392
|
+
get when() {
|
|
393
|
+
return props.visible !== false;
|
|
394
|
+
},
|
|
395
|
+
get children() {
|
|
396
|
+
var _el$8 = _tmpl$6(), _el$9 = _el$8.firstChild, _el$0 = _el$9.firstChild;
|
|
397
|
+
var _ref$3 = ref;
|
|
398
|
+
typeof _ref$3 === "function" ? web.use(_ref$3, _el$8) : ref = _el$8;
|
|
399
|
+
web.effect((_p$) => {
|
|
400
|
+
var _v$5 = `${computedPosition().top}px`, _v$6 = `${computedPosition().left}px`, _v$7 = opacity(), _v$8 = `${Math.min(100, Math.max(0, props.progress * 100))}%`;
|
|
401
|
+
_v$5 !== _p$.e && web.setStyleProperty(_el$8, "top", _p$.e = _v$5);
|
|
402
|
+
_v$6 !== _p$.t && web.setStyleProperty(_el$8, "left", _p$.t = _v$6);
|
|
403
|
+
_v$7 !== _p$.a && web.setStyleProperty(_el$8, "opacity", _p$.a = _v$7);
|
|
404
|
+
_v$8 !== _p$.o && web.setStyleProperty(_el$0, "width", _p$.o = _v$8);
|
|
405
|
+
return _p$;
|
|
406
|
+
}, {
|
|
407
|
+
e: void 0,
|
|
408
|
+
t: void 0,
|
|
409
|
+
a: void 0,
|
|
410
|
+
o: void 0
|
|
411
|
+
});
|
|
412
|
+
return _el$8;
|
|
413
|
+
}
|
|
414
|
+
});
|
|
431
415
|
};
|
|
432
|
-
var
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
416
|
+
var ReactGrabOverlay = (props) => {
|
|
417
|
+
return [web.createComponent(solidJs.Show, {
|
|
418
|
+
get when() {
|
|
419
|
+
return web.memo(() => !!props.selectionVisible)() && props.selectionBounds;
|
|
420
|
+
},
|
|
421
|
+
get children() {
|
|
422
|
+
return web.createComponent(Overlay, {
|
|
423
|
+
variant: "selection",
|
|
424
|
+
get bounds() {
|
|
425
|
+
return props.selectionBounds;
|
|
426
|
+
},
|
|
427
|
+
get visible() {
|
|
428
|
+
return props.selectionVisible;
|
|
429
|
+
},
|
|
430
|
+
lerpFactor: SELECTION_LERP_FACTOR
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
}), web.createComponent(solidJs.Show, {
|
|
434
|
+
get when() {
|
|
435
|
+
return web.memo(() => !!props.marqueeVisible)() && props.marqueeBounds;
|
|
436
|
+
},
|
|
437
|
+
get children() {
|
|
438
|
+
return web.createComponent(Overlay, {
|
|
439
|
+
variant: "marquee",
|
|
440
|
+
get bounds() {
|
|
441
|
+
return props.marqueeBounds;
|
|
442
|
+
},
|
|
443
|
+
get visible() {
|
|
444
|
+
return props.marqueeVisible;
|
|
445
|
+
},
|
|
446
|
+
lerpFactor: MARQUEE_LERP_FACTOR
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}), web.createComponent(solidJs.For, {
|
|
450
|
+
get each() {
|
|
451
|
+
return props.grabbedOverlays ?? [];
|
|
452
|
+
},
|
|
453
|
+
children: (overlay) => web.createComponent(Overlay, {
|
|
454
|
+
variant: "grabbed",
|
|
455
|
+
get bounds() {
|
|
456
|
+
return overlay.bounds;
|
|
457
|
+
},
|
|
458
|
+
visible: true
|
|
459
|
+
})
|
|
460
|
+
}), web.createComponent(solidJs.For, {
|
|
461
|
+
get each() {
|
|
462
|
+
return props.successLabels ?? [];
|
|
463
|
+
},
|
|
464
|
+
children: (label) => web.createComponent(Label, {
|
|
465
|
+
variant: "success",
|
|
466
|
+
get text() {
|
|
467
|
+
return label.text;
|
|
468
|
+
},
|
|
469
|
+
get x() {
|
|
470
|
+
return label.x;
|
|
471
|
+
},
|
|
472
|
+
get y() {
|
|
473
|
+
return label.y;
|
|
474
|
+
},
|
|
475
|
+
visible: true,
|
|
476
|
+
zIndex: 2147483648
|
|
477
|
+
})
|
|
478
|
+
}), web.createComponent(solidJs.Show, {
|
|
479
|
+
get when() {
|
|
480
|
+
return web.memo(() => !!(props.labelVisible && props.labelVariant && props.labelText && props.labelX !== void 0))() && props.labelY !== void 0;
|
|
481
|
+
},
|
|
482
|
+
get children() {
|
|
483
|
+
return web.createComponent(Label, {
|
|
484
|
+
get variant() {
|
|
485
|
+
return props.labelVariant;
|
|
486
|
+
},
|
|
487
|
+
get text() {
|
|
488
|
+
return props.labelText;
|
|
489
|
+
},
|
|
490
|
+
get x() {
|
|
491
|
+
return props.labelX;
|
|
492
|
+
},
|
|
493
|
+
get y() {
|
|
494
|
+
return props.labelY;
|
|
495
|
+
},
|
|
496
|
+
get visible() {
|
|
497
|
+
return props.labelVisible;
|
|
498
|
+
},
|
|
499
|
+
get zIndex() {
|
|
500
|
+
return props.labelZIndex;
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}), web.createComponent(solidJs.Show, {
|
|
505
|
+
get when() {
|
|
506
|
+
return web.memo(() => !!(props.progressVisible && props.progress !== void 0 && props.mouseX !== void 0))() && props.mouseY !== void 0;
|
|
507
|
+
},
|
|
508
|
+
get children() {
|
|
509
|
+
return web.createComponent(ProgressIndicator, {
|
|
510
|
+
get progress() {
|
|
511
|
+
return props.progress;
|
|
512
|
+
},
|
|
513
|
+
get mouseX() {
|
|
514
|
+
return props.mouseX;
|
|
515
|
+
},
|
|
516
|
+
get mouseY() {
|
|
517
|
+
return props.mouseY;
|
|
518
|
+
},
|
|
519
|
+
get visible() {
|
|
520
|
+
return props.progressVisible;
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
})];
|
|
437
525
|
};
|
|
438
526
|
bippy.instrument({
|
|
439
527
|
onCommitFiberRoot(_, fiberRoot) {
|
|
@@ -650,7 +738,19 @@ var getHTMLSnippet = (element) => {
|
|
|
650
738
|
};
|
|
651
739
|
|
|
652
740
|
// src/utils/copy-content.ts
|
|
741
|
+
var waitForFocus = () => {
|
|
742
|
+
if (document.hasFocus()) return Promise.resolve();
|
|
743
|
+
return new Promise((resolve) => {
|
|
744
|
+
const onFocus = () => {
|
|
745
|
+
window.removeEventListener("focus", onFocus);
|
|
746
|
+
resolve();
|
|
747
|
+
};
|
|
748
|
+
window.addEventListener("focus", onFocus);
|
|
749
|
+
window.focus();
|
|
750
|
+
});
|
|
751
|
+
};
|
|
653
752
|
var copyContent = async (content) => {
|
|
753
|
+
await waitForFocus();
|
|
654
754
|
try {
|
|
655
755
|
if (Array.isArray(content)) {
|
|
656
756
|
if (!navigator?.clipboard?.write) {
|
|
@@ -712,218 +812,455 @@ var copyContentFallback = (content) => {
|
|
|
712
812
|
}
|
|
713
813
|
};
|
|
714
814
|
|
|
715
|
-
// src/core.
|
|
815
|
+
// src/core.tsx
|
|
716
816
|
var init = (rawOptions) => {
|
|
717
817
|
const options = {
|
|
718
818
|
enabled: true,
|
|
719
|
-
keyHoldDuration:
|
|
819
|
+
keyHoldDuration: 300,
|
|
720
820
|
...rawOptions
|
|
721
821
|
};
|
|
722
822
|
if (options.enabled === false) {
|
|
723
823
|
return;
|
|
724
824
|
}
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
825
|
+
return solidJs.createRoot((dispose) => {
|
|
826
|
+
const [isHoldingKeys, setIsHoldingKeys] = solidJs.createSignal(false);
|
|
827
|
+
const [mouseX, setMouseX] = solidJs.createSignal(-1e3);
|
|
828
|
+
const [mouseY, setMouseY] = solidJs.createSignal(-1e3);
|
|
829
|
+
const [isDragging, setIsDragging] = solidJs.createSignal(false);
|
|
830
|
+
const [dragStartX, setDragStartX] = solidJs.createSignal(-1e3);
|
|
831
|
+
const [dragStartY, setDragStartY] = solidJs.createSignal(-1e3);
|
|
832
|
+
const [isCopying, setIsCopying] = solidJs.createSignal(false);
|
|
833
|
+
const [lastGrabbedElement, setLastGrabbedElement] = solidJs.createSignal(null);
|
|
834
|
+
const [progressStartTime, setProgressStartTime] = solidJs.createSignal(null);
|
|
835
|
+
const [progressTick, setProgressTick] = solidJs.createSignal(0);
|
|
836
|
+
const [grabbedOverlays, setGrabbedOverlays] = solidJs.createSignal([]);
|
|
837
|
+
const [successLabels, setSuccessLabels] = solidJs.createSignal([]);
|
|
838
|
+
const [isActivated, setIsActivated] = solidJs.createSignal(false);
|
|
839
|
+
const [showProgressIndicator, setShowProgressIndicator] = solidJs.createSignal(false);
|
|
840
|
+
let holdTimerId = null;
|
|
841
|
+
let progressAnimationId = null;
|
|
842
|
+
let progressDelayTimerId = null;
|
|
843
|
+
const isOverlayActive = solidJs.createMemo(() => isActivated() && !isCopying());
|
|
844
|
+
const isTargetKeyCombination = (event) => (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "c";
|
|
845
|
+
const getElementAtPosition = (x, y) => {
|
|
846
|
+
const elementsAtPoint = document.elementsFromPoint(x, y);
|
|
847
|
+
for (const candidateElement of elementsAtPoint) {
|
|
848
|
+
if (candidateElement.closest(`[${ATTRIBUTE_NAME}]`)) {
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
const computedStyle = window.getComputedStyle(candidateElement);
|
|
852
|
+
if (!isElementVisible(candidateElement, computedStyle)) {
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
return candidateElement;
|
|
856
|
+
}
|
|
857
|
+
return null;
|
|
858
|
+
};
|
|
859
|
+
const getElementsInMarquee = (marqueeRect) => {
|
|
860
|
+
const elements = [];
|
|
861
|
+
const allElements = Array.from(document.querySelectorAll("*"));
|
|
862
|
+
const marqueeLeft = marqueeRect.x;
|
|
863
|
+
const marqueeTop = marqueeRect.y;
|
|
864
|
+
const marqueeRight = marqueeRect.x + marqueeRect.width;
|
|
865
|
+
const marqueeBottom = marqueeRect.y + marqueeRect.height;
|
|
866
|
+
for (const candidateElement of allElements) {
|
|
867
|
+
if (candidateElement.closest(`[${ATTRIBUTE_NAME}]`)) {
|
|
868
|
+
continue;
|
|
869
|
+
}
|
|
870
|
+
const computedStyle = window.getComputedStyle(candidateElement);
|
|
871
|
+
if (!isElementVisible(candidateElement, computedStyle)) {
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
const rect = candidateElement.getBoundingClientRect();
|
|
875
|
+
const elementLeft = rect.left;
|
|
876
|
+
const elementTop = rect.top;
|
|
877
|
+
const elementRight = rect.left + rect.width;
|
|
878
|
+
const elementBottom = rect.top + rect.height;
|
|
879
|
+
const intersectionLeft = Math.max(marqueeLeft, elementLeft);
|
|
880
|
+
const intersectionTop = Math.max(marqueeTop, elementTop);
|
|
881
|
+
const intersectionRight = Math.min(marqueeRight, elementRight);
|
|
882
|
+
const intersectionBottom = Math.min(marqueeBottom, elementBottom);
|
|
883
|
+
const intersectionWidth = Math.max(0, intersectionRight - intersectionLeft);
|
|
884
|
+
const intersectionHeight = Math.max(0, intersectionBottom - intersectionTop);
|
|
885
|
+
const intersectionArea = intersectionWidth * intersectionHeight;
|
|
886
|
+
const elementArea = Math.max(0, rect.width * rect.height);
|
|
887
|
+
const COVERAGE_THRESHOLD = 0.75;
|
|
888
|
+
const hasMajorityCoverage = elementArea > 0 && intersectionArea / elementArea >= COVERAGE_THRESHOLD;
|
|
889
|
+
if (hasMajorityCoverage) {
|
|
890
|
+
elements.push(candidateElement);
|
|
891
|
+
}
|
|
742
892
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
893
|
+
return elements;
|
|
894
|
+
};
|
|
895
|
+
const getElementsInMarqueeLoose = (marqueeRect) => {
|
|
896
|
+
const elements = [];
|
|
897
|
+
const allElements = Array.from(document.querySelectorAll("*"));
|
|
898
|
+
const marqueeLeft = marqueeRect.x;
|
|
899
|
+
const marqueeTop = marqueeRect.y;
|
|
900
|
+
const marqueeRight = marqueeRect.x + marqueeRect.width;
|
|
901
|
+
const marqueeBottom = marqueeRect.y + marqueeRect.height;
|
|
902
|
+
for (const candidateElement of allElements) {
|
|
903
|
+
if (candidateElement.closest(`[${ATTRIBUTE_NAME}]`)) {
|
|
904
|
+
continue;
|
|
905
|
+
}
|
|
906
|
+
const tag = (candidateElement.tagName || "").toUpperCase();
|
|
907
|
+
if (tag === "HTML" || tag === "BODY") continue;
|
|
908
|
+
const computedStyle = window.getComputedStyle(candidateElement);
|
|
909
|
+
if (!isElementVisible(candidateElement, computedStyle)) {
|
|
910
|
+
continue;
|
|
911
|
+
}
|
|
912
|
+
const rect = candidateElement.getBoundingClientRect();
|
|
913
|
+
const elementLeft = rect.left;
|
|
914
|
+
const elementTop = rect.top;
|
|
915
|
+
const elementRight = rect.left + rect.width;
|
|
916
|
+
const elementBottom = rect.top + rect.height;
|
|
917
|
+
const intersects = elementLeft < marqueeRight && elementRight > marqueeLeft && elementTop < marqueeBottom && elementBottom > marqueeTop;
|
|
918
|
+
if (intersects) {
|
|
919
|
+
elements.push(candidateElement);
|
|
920
|
+
}
|
|
746
921
|
}
|
|
747
|
-
return
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
};
|
|
751
|
-
const wrapInReferencedElement = (content) => `
|
|
922
|
+
return elements;
|
|
923
|
+
};
|
|
924
|
+
const wrapInReferencedElement = (content) => `
|
|
752
925
|
|
|
753
926
|
<referenced_element>
|
|
754
927
|
${content}
|
|
755
928
|
</referenced_element>`;
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
929
|
+
const wrapInReferencedElements = (content) => `
|
|
930
|
+
|
|
931
|
+
<referenced_elements>
|
|
932
|
+
${content}
|
|
933
|
+
</referenced_elements>`;
|
|
934
|
+
const addGrabbedOverlay = (bounds) => {
|
|
935
|
+
const id = `grabbed-${Date.now()}-${Math.random()}`;
|
|
936
|
+
setGrabbedOverlays((prev) => [...prev, {
|
|
937
|
+
id,
|
|
938
|
+
bounds
|
|
939
|
+
}]);
|
|
940
|
+
setTimeout(() => {
|
|
941
|
+
setGrabbedOverlays((prev) => prev.filter((overlay) => overlay.id !== id));
|
|
942
|
+
}, 300);
|
|
943
|
+
};
|
|
944
|
+
const addSuccessLabel = (text, x, y) => {
|
|
945
|
+
const id = `success-${Date.now()}-${Math.random()}`;
|
|
946
|
+
setSuccessLabels((prev) => [...prev, {
|
|
947
|
+
id,
|
|
948
|
+
text,
|
|
949
|
+
x,
|
|
950
|
+
y
|
|
951
|
+
}]);
|
|
952
|
+
setTimeout(() => {
|
|
953
|
+
setSuccessLabels((prev) => prev.filter((label) => label.id !== id));
|
|
954
|
+
}, 1700);
|
|
955
|
+
};
|
|
956
|
+
const handleCopy = async (targetElement2) => {
|
|
957
|
+
const elementBounds = targetElement2.getBoundingClientRect();
|
|
958
|
+
const tagName = (targetElement2.tagName || "").toLowerCase();
|
|
959
|
+
addGrabbedOverlay({
|
|
960
|
+
borderRadius: window.getComputedStyle(targetElement2).borderRadius || "0px",
|
|
961
|
+
height: elementBounds.height,
|
|
962
|
+
transform: window.getComputedStyle(targetElement2).transform || "none",
|
|
963
|
+
width: elementBounds.width,
|
|
964
|
+
x: elementBounds.left,
|
|
965
|
+
y: elementBounds.top
|
|
966
|
+
});
|
|
967
|
+
try {
|
|
968
|
+
const elementHtml = getHTMLSnippet(targetElement2);
|
|
969
|
+
await copyContent(wrapInReferencedElement(elementHtml));
|
|
970
|
+
const componentStackTrace = await getSourceTrace(targetElement2);
|
|
971
|
+
if (componentStackTrace?.length) {
|
|
972
|
+
const formattedStackTrace = componentStackTrace.map((source) => ` ${source.functionName} - ${source.fileName}:${source.lineNumber}:${source.columnNumber}`).join("\n");
|
|
973
|
+
await copyContent(wrapInReferencedElement(`${elementHtml}
|
|
775
974
|
|
|
776
975
|
Component owner stack:
|
|
777
|
-
${formattedStackTrace}`
|
|
778
|
-
|
|
779
|
-
|
|
976
|
+
${formattedStackTrace}`));
|
|
977
|
+
}
|
|
978
|
+
} catch {
|
|
780
979
|
}
|
|
781
|
-
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
980
|
+
addSuccessLabel(tagName ? `<${tagName}>` : "<element>", elementBounds.left, elementBounds.top);
|
|
981
|
+
};
|
|
982
|
+
const handleMultipleCopy = async (targetElements) => {
|
|
983
|
+
if (targetElements.length === 0) return;
|
|
984
|
+
let minX = Infinity;
|
|
985
|
+
let minY = Infinity;
|
|
986
|
+
for (const element of targetElements) {
|
|
987
|
+
const elementBounds = element.getBoundingClientRect();
|
|
988
|
+
minX = Math.min(minX, elementBounds.left);
|
|
989
|
+
minY = Math.min(minY, elementBounds.top);
|
|
990
|
+
addGrabbedOverlay({
|
|
991
|
+
borderRadius: window.getComputedStyle(element).borderRadius || "0px",
|
|
992
|
+
height: elementBounds.height,
|
|
993
|
+
transform: window.getComputedStyle(element).transform || "none",
|
|
994
|
+
width: elementBounds.width,
|
|
995
|
+
x: elementBounds.left,
|
|
996
|
+
y: elementBounds.top
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
try {
|
|
1000
|
+
const elementSnippets = [];
|
|
1001
|
+
for (const element of targetElements) {
|
|
1002
|
+
const elementHtml = getHTMLSnippet(element);
|
|
1003
|
+
const componentStackTrace = await getSourceTrace(element);
|
|
1004
|
+
if (componentStackTrace?.length) {
|
|
1005
|
+
const formattedStackTrace = componentStackTrace.map((source) => ` ${source.functionName} - ${source.fileName}:${source.lineNumber}:${source.columnNumber}`).join("\n");
|
|
1006
|
+
elementSnippets.push(`${elementHtml}
|
|
1007
|
+
|
|
1008
|
+
Component owner stack:
|
|
1009
|
+
${formattedStackTrace}`);
|
|
1010
|
+
} else {
|
|
1011
|
+
elementSnippets.push(elementHtml);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
const combinedContent = elementSnippets.join("\n\n---\n\n");
|
|
1015
|
+
await copyContent(wrapInReferencedElements(combinedContent));
|
|
1016
|
+
} catch {
|
|
1017
|
+
}
|
|
1018
|
+
addSuccessLabel(`${targetElements.length} elements`, minX, minY);
|
|
1019
|
+
};
|
|
1020
|
+
const targetElement = solidJs.createMemo(() => {
|
|
1021
|
+
if (!isOverlayActive() || isDragging()) return null;
|
|
1022
|
+
return getElementAtPosition(mouseX(), mouseY());
|
|
1023
|
+
});
|
|
1024
|
+
const selectionBounds = solidJs.createMemo(() => {
|
|
1025
|
+
const element = targetElement();
|
|
1026
|
+
if (!element) return void 0;
|
|
1027
|
+
const last = lastGrabbedElement();
|
|
1028
|
+
if (last && element === last) return void 0;
|
|
1029
|
+
const elementBounds = element.getBoundingClientRect();
|
|
1030
|
+
const computedStyle = window.getComputedStyle(element);
|
|
1031
|
+
return {
|
|
1032
|
+
borderRadius: computedStyle.borderRadius || "0px",
|
|
1033
|
+
height: elementBounds.height,
|
|
1034
|
+
transform: computedStyle.transform || "none",
|
|
1035
|
+
width: elementBounds.width,
|
|
1036
|
+
x: elementBounds.left,
|
|
1037
|
+
y: elementBounds.top
|
|
1038
|
+
};
|
|
1039
|
+
});
|
|
1040
|
+
const marqueeBounds = solidJs.createMemo(() => {
|
|
1041
|
+
if (!isDragging()) return void 0;
|
|
1042
|
+
const marqueeX = Math.min(dragStartX(), mouseX());
|
|
1043
|
+
const marqueeY = Math.min(dragStartY(), mouseY());
|
|
1044
|
+
const marqueeWidth = Math.abs(mouseX() - dragStartX());
|
|
1045
|
+
const marqueeHeight = Math.abs(mouseY() - dragStartY());
|
|
1046
|
+
return {
|
|
1047
|
+
borderRadius: "0px",
|
|
1048
|
+
height: marqueeHeight,
|
|
1049
|
+
transform: "none",
|
|
1050
|
+
width: marqueeWidth,
|
|
1051
|
+
x: marqueeX,
|
|
1052
|
+
y: marqueeY
|
|
1053
|
+
};
|
|
1054
|
+
});
|
|
1055
|
+
const labelText = solidJs.createMemo(() => {
|
|
1056
|
+
const element = targetElement();
|
|
1057
|
+
if (!element) return "";
|
|
1058
|
+
const tagName = (element.tagName || "").toLowerCase();
|
|
1059
|
+
return tagName ? `<${tagName}>` : "<element>";
|
|
1060
|
+
});
|
|
1061
|
+
const labelPosition = solidJs.createMemo(() => {
|
|
1062
|
+
const element = targetElement() ?? lastGrabbedElement();
|
|
1063
|
+
if (element) {
|
|
1064
|
+
const rect = element.getBoundingClientRect();
|
|
1065
|
+
return {
|
|
1066
|
+
x: rect.left,
|
|
1067
|
+
y: rect.top
|
|
1068
|
+
};
|
|
1069
|
+
}
|
|
1070
|
+
return {
|
|
1071
|
+
x: mouseX(),
|
|
1072
|
+
y: mouseY()
|
|
1073
|
+
};
|
|
1074
|
+
});
|
|
1075
|
+
const isSameAsLast = solidJs.createMemo(() => {
|
|
1076
|
+
const current = targetElement();
|
|
1077
|
+
const last = lastGrabbedElement();
|
|
1078
|
+
return !!current && current === last;
|
|
1079
|
+
});
|
|
1080
|
+
solidJs.createEffect(() => {
|
|
1081
|
+
const current = targetElement();
|
|
1082
|
+
const last = lastGrabbedElement();
|
|
1083
|
+
if (last && current && last !== current) {
|
|
1084
|
+
setLastGrabbedElement(null);
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
const progress = solidJs.createMemo(() => {
|
|
1088
|
+
const startTime = progressStartTime();
|
|
1089
|
+
progressTick();
|
|
1090
|
+
if (startTime === null) return 0;
|
|
1091
|
+
const elapsed = Date.now() - startTime;
|
|
1092
|
+
return Math.min(elapsed / options.keyHoldDuration, 1);
|
|
1093
|
+
});
|
|
1094
|
+
const startProgressAnimation = () => {
|
|
1095
|
+
setProgressStartTime(Date.now());
|
|
1096
|
+
setShowProgressIndicator(false);
|
|
1097
|
+
progressDelayTimerId = window.setTimeout(() => {
|
|
1098
|
+
setShowProgressIndicator(true);
|
|
1099
|
+
progressDelayTimerId = null;
|
|
1100
|
+
}, 150);
|
|
1101
|
+
const animateProgress = () => {
|
|
1102
|
+
if (progressStartTime() === null) return;
|
|
1103
|
+
setProgressTick((t) => t + 1);
|
|
1104
|
+
const currentProgress = progress();
|
|
1105
|
+
if (currentProgress < 1) {
|
|
1106
|
+
progressAnimationId = requestAnimationFrame(animateProgress);
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
animateProgress();
|
|
1110
|
+
};
|
|
1111
|
+
const stopProgressAnimation = () => {
|
|
1112
|
+
if (progressAnimationId !== null) {
|
|
1113
|
+
cancelAnimationFrame(progressAnimationId);
|
|
1114
|
+
progressAnimationId = null;
|
|
1115
|
+
}
|
|
1116
|
+
if (progressDelayTimerId !== null) {
|
|
1117
|
+
window.clearTimeout(progressDelayTimerId);
|
|
1118
|
+
progressDelayTimerId = null;
|
|
1119
|
+
}
|
|
1120
|
+
setProgressStartTime(null);
|
|
1121
|
+
setShowProgressIndicator(false);
|
|
1122
|
+
};
|
|
1123
|
+
const activateOverlay = () => {
|
|
1124
|
+
stopProgressAnimation();
|
|
1125
|
+
setIsActivated(true);
|
|
1126
|
+
};
|
|
1127
|
+
const abortController = new AbortController();
|
|
1128
|
+
const signal = abortController.signal;
|
|
1129
|
+
window.addEventListener("keydown", (event) => {
|
|
1130
|
+
if (event.key === "Escape" && isHoldingKeys()) {
|
|
1131
|
+
setIsHoldingKeys(false);
|
|
1132
|
+
setIsActivated(false);
|
|
1133
|
+
if (holdTimerId) window.clearTimeout(holdTimerId);
|
|
1134
|
+
stopProgressAnimation();
|
|
810
1135
|
return;
|
|
811
1136
|
}
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
1137
|
+
if (isKeyboardEventTriggeredByInput(event)) return;
|
|
1138
|
+
if (isTargetKeyCombination(event) && !isHoldingKeys()) {
|
|
1139
|
+
setIsHoldingKeys(true);
|
|
1140
|
+
startProgressAnimation();
|
|
1141
|
+
holdTimerId = window.setTimeout(() => {
|
|
1142
|
+
activateOverlay();
|
|
1143
|
+
options.onActivate?.();
|
|
1144
|
+
}, options.keyHoldDuration);
|
|
1145
|
+
}
|
|
1146
|
+
}, {
|
|
1147
|
+
signal
|
|
823
1148
|
});
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
if (renderFrameId !== null) return;
|
|
834
|
-
renderFrameId = requestAnimationFrame(() => {
|
|
835
|
-
renderFrameId = null;
|
|
836
|
-
handleRender();
|
|
1149
|
+
window.addEventListener("keyup", (event) => {
|
|
1150
|
+
if (isHoldingKeys() && (!isTargetKeyCombination(event) || event.key.toLowerCase() === "c")) {
|
|
1151
|
+
setIsHoldingKeys(false);
|
|
1152
|
+
setIsActivated(false);
|
|
1153
|
+
if (holdTimerId) window.clearTimeout(holdTimerId);
|
|
1154
|
+
stopProgressAnimation();
|
|
1155
|
+
}
|
|
1156
|
+
}, {
|
|
1157
|
+
signal
|
|
837
1158
|
});
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
const handleMouseMove = (event) => {
|
|
844
|
-
mouseX = event.clientX;
|
|
845
|
-
mouseY = event.clientY;
|
|
846
|
-
scheduleRender();
|
|
847
|
-
};
|
|
848
|
-
const handleVisibilityChange = () => {
|
|
849
|
-
if (document.hidden) {
|
|
850
|
-
cleanupGrabbedIndicators();
|
|
851
|
-
hideLabel();
|
|
852
|
-
}
|
|
853
|
-
};
|
|
854
|
-
const handleSelectionClick = () => {
|
|
855
|
-
if (!hoveredElement || isCopying) return;
|
|
856
|
-
isCopying = true;
|
|
857
|
-
lastGrabbedElement = hoveredElement;
|
|
858
|
-
const targetElement = hoveredElement;
|
|
859
|
-
const computedStyle = window.getComputedStyle(targetElement);
|
|
860
|
-
const elementBounds = targetElement.getBoundingClientRect();
|
|
861
|
-
createGrabbedOverlay(overlayRoot, {
|
|
862
|
-
borderRadius: computedStyle.borderRadius || "0px",
|
|
863
|
-
height: elementBounds.height,
|
|
864
|
-
transform: computedStyle.transform || "none",
|
|
865
|
-
width: elementBounds.width,
|
|
866
|
-
x: elementBounds.left,
|
|
867
|
-
y: elementBounds.top
|
|
1159
|
+
window.addEventListener("mousemove", (event) => {
|
|
1160
|
+
setMouseX(event.clientX);
|
|
1161
|
+
setMouseY(event.clientY);
|
|
1162
|
+
}, {
|
|
1163
|
+
signal
|
|
868
1164
|
});
|
|
869
|
-
|
|
870
|
-
isCopying
|
|
871
|
-
|
|
1165
|
+
window.addEventListener("mousedown", (event) => {
|
|
1166
|
+
if (!isOverlayActive() || isCopying()) return;
|
|
1167
|
+
setIsDragging(true);
|
|
1168
|
+
setDragStartX(event.clientX);
|
|
1169
|
+
setDragStartY(event.clientY);
|
|
1170
|
+
}, {
|
|
1171
|
+
signal
|
|
872
1172
|
});
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
)
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1173
|
+
window.addEventListener("mouseup", (event) => {
|
|
1174
|
+
if (!isDragging()) return;
|
|
1175
|
+
const dragDistanceX = Math.abs(event.clientX - dragStartX());
|
|
1176
|
+
const dragDistanceY = Math.abs(event.clientY - dragStartY());
|
|
1177
|
+
const DRAG_THRESHOLD = 5;
|
|
1178
|
+
const wasDrag = dragDistanceX > DRAG_THRESHOLD || dragDistanceY > DRAG_THRESHOLD;
|
|
1179
|
+
setIsDragging(false);
|
|
1180
|
+
if (wasDrag) {
|
|
1181
|
+
const marqueeX = Math.min(dragStartX(), event.clientX);
|
|
1182
|
+
const marqueeY = Math.min(dragStartY(), event.clientY);
|
|
1183
|
+
const marqueeWidth = Math.abs(event.clientX - dragStartX());
|
|
1184
|
+
const marqueeHeight = Math.abs(event.clientY - dragStartY());
|
|
1185
|
+
const elements = getElementsInMarquee({
|
|
1186
|
+
x: marqueeX,
|
|
1187
|
+
y: marqueeY,
|
|
1188
|
+
width: marqueeWidth,
|
|
1189
|
+
height: marqueeHeight
|
|
1190
|
+
});
|
|
1191
|
+
if (elements.length > 0) {
|
|
1192
|
+
setIsCopying(true);
|
|
1193
|
+
void handleMultipleCopy(elements).finally(() => {
|
|
1194
|
+
setIsCopying(false);
|
|
1195
|
+
});
|
|
1196
|
+
} else {
|
|
1197
|
+
const fallbackElements = getElementsInMarqueeLoose({
|
|
1198
|
+
x: marqueeX,
|
|
1199
|
+
y: marqueeY,
|
|
1200
|
+
width: marqueeWidth,
|
|
1201
|
+
height: marqueeHeight
|
|
1202
|
+
});
|
|
1203
|
+
if (fallbackElements.length > 0) {
|
|
1204
|
+
setIsCopying(true);
|
|
1205
|
+
void handleMultipleCopy(fallbackElements).finally(() => {
|
|
1206
|
+
setIsCopying(false);
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
} else {
|
|
1211
|
+
const element = getElementAtPosition(event.clientX, event.clientY);
|
|
1212
|
+
if (!element) return;
|
|
1213
|
+
setIsCopying(true);
|
|
1214
|
+
setLastGrabbedElement(element);
|
|
1215
|
+
void handleCopy(element).finally(() => {
|
|
1216
|
+
setIsCopying(false);
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
}, {
|
|
1220
|
+
signal
|
|
1221
|
+
});
|
|
1222
|
+
window.addEventListener("scroll", () => {
|
|
1223
|
+
}, {
|
|
1224
|
+
signal,
|
|
1225
|
+
capture: true
|
|
1226
|
+
});
|
|
1227
|
+
window.addEventListener("resize", () => {
|
|
1228
|
+
}, {
|
|
1229
|
+
signal
|
|
1230
|
+
});
|
|
1231
|
+
document.addEventListener("visibilitychange", () => {
|
|
1232
|
+
if (document.hidden) {
|
|
1233
|
+
setGrabbedOverlays([]);
|
|
1234
|
+
}
|
|
1235
|
+
}, {
|
|
1236
|
+
signal
|
|
1237
|
+
});
|
|
1238
|
+
solidJs.onCleanup(() => {
|
|
1239
|
+
abortController.abort();
|
|
1240
|
+
if (holdTimerId) window.clearTimeout(holdTimerId);
|
|
1241
|
+
stopProgressAnimation();
|
|
1242
|
+
});
|
|
1243
|
+
const overlayRoot = mountRoot();
|
|
1244
|
+
const overlayProps = solidJs.createMemo(() => ({
|
|
1245
|
+
selectionVisible: isOverlayActive() && !isDragging() && !!selectionBounds(),
|
|
1246
|
+
selectionBounds: selectionBounds(),
|
|
1247
|
+
marqueeVisible: isOverlayActive() && isDragging(),
|
|
1248
|
+
marqueeBounds: marqueeBounds(),
|
|
1249
|
+
grabbedOverlays: grabbedOverlays(),
|
|
1250
|
+
successLabels: successLabels(),
|
|
1251
|
+
labelVariant: isCopying() ? "processing" : "hover",
|
|
1252
|
+
labelText: labelText(),
|
|
1253
|
+
labelX: labelPosition().x,
|
|
1254
|
+
labelY: labelPosition().y,
|
|
1255
|
+
labelVisible: isOverlayActive() && !isDragging() && !!targetElement() && !isSameAsLast() || isCopying(),
|
|
1256
|
+
progressVisible: isHoldingKeys() && showProgressIndicator(),
|
|
1257
|
+
progress: progress(),
|
|
1258
|
+
mouseX: mouseX(),
|
|
1259
|
+
mouseY: mouseY()
|
|
1260
|
+
}));
|
|
1261
|
+
web.render(() => web.createComponent(ReactGrabOverlay, web.mergeProps(overlayProps)), overlayRoot);
|
|
1262
|
+
return dispose;
|
|
1263
|
+
});
|
|
927
1264
|
};
|
|
928
1265
|
|
|
929
1266
|
// src/index.ts
|