react-grab 0.1.24 → 0.1.26
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/README.md +109 -7
- package/dist/chunk-447CSJVY.js +26 -0
- package/dist/chunk-EMBZHHMN.js +101 -0
- package/dist/chunk-GGMYMQUS.cjs +101 -0
- package/dist/chunk-LCM4WNAK.cjs +26 -0
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.d.cts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/{index-BurXddDF.d.cts → index-CN8HkCli.d.cts} +2 -2
- package/dist/{index-BurXddDF.d.ts → index-CN8HkCli.d.ts} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.global.js +37 -37
- package/dist/index.js +1 -1
- package/dist/primitives.cjs +2 -2
- package/dist/primitives.d.cts +6 -2
- package/dist/primitives.d.ts +6 -2
- package/dist/primitives.js +2 -2
- package/dist/styles.css +1 -1
- package/package.json +3 -13
- package/dist/chunk-CHTY5GHQ.cjs +0 -26
- package/dist/chunk-UERZTOK6.js +0 -101
- package/dist/chunk-XWSK4QRO.cjs +0 -101
- package/dist/chunk-Z5IMKMDB.js +0 -26
- package/dist/react.cjs +0 -19239
- package/dist/react.d.cts +0 -345
- package/dist/react.d.ts +0 -345
- package/dist/react.js +0 -19225
package/README.md
CHANGED
|
@@ -201,15 +201,117 @@ actions: [
|
|
|
201
201
|
];
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
See [`packages/react-grab/src/types.ts`](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/types.ts) for the full `Plugin`, `PluginHooks`, and `PluginConfig` interfaces.
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
- **`hooks`** — lifecycle callbacks like `onActivate`, `onElementSelect`, `onCopySuccess`, `transformCopyContent`, etc. (see `PluginHooks`)
|
|
208
|
-
- **`theme`** — partial theme overrides (see `Theme`)
|
|
209
|
-
- **`options`** — override default options like `activationMode` or `keyHoldDuration`
|
|
210
|
-
- **`setup(api)`** — a function that receives the full `ReactGrabAPI` and can return additional config or a `cleanup` function
|
|
206
|
+
## Primitives
|
|
211
207
|
|
|
212
|
-
|
|
208
|
+
React Grab provides a set of primitives for building your own mini React Grab.
|
|
209
|
+
|
|
210
|
+
Here's a simple example of how to build your own element selector with hover highlight and one-click inspection:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
npm install react-grab@latest
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Then, put this in your React app:
|
|
217
|
+
|
|
218
|
+
```tsx
|
|
219
|
+
import { useState } from "react";
|
|
220
|
+
import {
|
|
221
|
+
getElementContext,
|
|
222
|
+
freeze,
|
|
223
|
+
unfreeze,
|
|
224
|
+
openFile,
|
|
225
|
+
type ReactGrabElementContext,
|
|
226
|
+
} from "react-grab/primitives";
|
|
227
|
+
|
|
228
|
+
const useElementSelector = (
|
|
229
|
+
onSelect: (context: ReactGrabElementContext) => void,
|
|
230
|
+
) => {
|
|
231
|
+
const [isActive, setIsActive] = useState(false);
|
|
232
|
+
|
|
233
|
+
const startSelecting = () => {
|
|
234
|
+
setIsActive(true);
|
|
235
|
+
|
|
236
|
+
const highlightOverlay = document.createElement("div");
|
|
237
|
+
Object.assign(highlightOverlay.style, {
|
|
238
|
+
position: "fixed",
|
|
239
|
+
pointerEvents: "none",
|
|
240
|
+
zIndex: "999999",
|
|
241
|
+
border: "2px solid #3b82f6",
|
|
242
|
+
transition: "all 75ms ease-out",
|
|
243
|
+
display: "none",
|
|
244
|
+
});
|
|
245
|
+
document.body.appendChild(highlightOverlay);
|
|
246
|
+
|
|
247
|
+
const handleMouseMove = ({ clientX, clientY }: MouseEvent) => {
|
|
248
|
+
highlightOverlay.style.display = "none";
|
|
249
|
+
const target = document.elementFromPoint(clientX, clientY);
|
|
250
|
+
if (!target) return;
|
|
251
|
+
const { top, left, width, height } = target.getBoundingClientRect();
|
|
252
|
+
Object.assign(highlightOverlay.style, {
|
|
253
|
+
top: `${top}px`,
|
|
254
|
+
left: `${left}px`,
|
|
255
|
+
width: `${width}px`,
|
|
256
|
+
height: `${height}px`,
|
|
257
|
+
display: "block",
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
const handleClick = async ({ clientX, clientY }: MouseEvent) => {
|
|
262
|
+
highlightOverlay.style.display = "none";
|
|
263
|
+
const target = document.elementFromPoint(clientX, clientY);
|
|
264
|
+
teardown();
|
|
265
|
+
if (!target) return;
|
|
266
|
+
freeze();
|
|
267
|
+
onSelect(await getElementContext(target));
|
|
268
|
+
unfreeze();
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const teardown = () => {
|
|
272
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
273
|
+
document.removeEventListener("click", handleClick, true);
|
|
274
|
+
highlightOverlay.remove();
|
|
275
|
+
setIsActive(false);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
279
|
+
document.addEventListener("click", handleClick, true);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
return { isActive, startSelecting };
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
const ElementSelector = () => {
|
|
286
|
+
const [context, setContext] = useState<ReactGrabElementContext | null>(null);
|
|
287
|
+
const selector = useElementSelector(setContext);
|
|
288
|
+
|
|
289
|
+
return (
|
|
290
|
+
<div>
|
|
291
|
+
<button onClick={selector.startSelecting} disabled={selector.isActive}>
|
|
292
|
+
{selector.isActive ? "Selecting…" : "Select Element"}
|
|
293
|
+
</button>
|
|
294
|
+
{context && (
|
|
295
|
+
<div>
|
|
296
|
+
<p>Component: {context.componentName}</p>
|
|
297
|
+
<p>Selector: {context.selector}</p>
|
|
298
|
+
<pre>{context.stackString}</pre>
|
|
299
|
+
<button
|
|
300
|
+
onClick={() => {
|
|
301
|
+
const frame = context.stack[0];
|
|
302
|
+
if (frame?.fileName) openFile(frame.fileName, frame.lineNumber);
|
|
303
|
+
}}
|
|
304
|
+
>
|
|
305
|
+
Open in Editor
|
|
306
|
+
</button>
|
|
307
|
+
</div>
|
|
308
|
+
)}
|
|
309
|
+
</div>
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
See [`packages/react-grab/src/primitives.ts`](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/primitives.ts) for the full `ReactGrabElementContext`, `getElementContext`, `freeze`, `unfreeze`, and `openFile` primitives.
|
|
213
315
|
|
|
214
316
|
## Resources & Contributing Back
|
|
215
317
|
|