react-grab 0.1.22 → 0.1.24

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.js CHANGED
@@ -1,4 +1,4 @@
1
- import {i}from'./chunk-H7IR3CM4.js';export{f as DEFAULT_THEME,g as commentPlugin,c as formatElementInfo,e as generateSnippet,b as getStack,i as init,a as isInstrumentationActive,h as openPlugin}from'./chunk-H7IR3CM4.js';/**
1
+ import {f}from'./chunk-Z5IMKMDB.js';export{c as DEFAULT_THEME,d as commentPlugin,b as generateSnippet,f as init,e as openPlugin}from'./chunk-Z5IMKMDB.js';export{wa as formatElementInfo,ra as getStack,la as isInstrumentationActive}from'./chunk-UERZTOK6.js';/**
2
2
  * @license MIT
3
3
  *
4
4
  * Copyright (c) 2025 Aiden Bai
@@ -6,4 +6,4 @@ import {i}from'./chunk-H7IR3CM4.js';export{f as DEFAULT_THEME,g as commentPlugin
6
6
  * This source code is licensed under the MIT license found in the
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
- var e=null,d=()=>typeof window>"u"?e:window.__REACT_GRAB__??e??null,c=t=>{e=t,typeof window<"u"&&(t?window.__REACT_GRAB__=t:delete window.__REACT_GRAB__);};typeof window<"u"&&(window.__REACT_GRAB__?e=window.__REACT_GRAB__:(e=i(),window.__REACT_GRAB__=e),window.dispatchEvent(new CustomEvent("react-grab:init",{detail:e})));export{d as getGlobalApi,c as setGlobalApi};
9
+ var e=null,d=()=>typeof window>"u"?e:window.__REACT_GRAB__??e??null,c=t=>{e=t,typeof window<"u"&&(t?window.__REACT_GRAB__=t:delete window.__REACT_GRAB__);};typeof window<"u"&&(window.__REACT_GRAB__?e=window.__REACT_GRAB__:(e=f(),window.__REACT_GRAB__=e),window.dispatchEvent(new CustomEvent("react-grab:init",{detail:e})));export{d as getGlobalApi,c as setGlobalApi};
@@ -0,0 +1,9 @@
1
+ 'use strict';var chunkXWSK4QRO_cjs=require('./chunk-XWSK4QRO.cjs');/**
2
+ * @license MIT
3
+ *
4
+ * Copyright (c) 2025 Aiden Bai
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ var H=async e=>{let t=await chunkXWSK4QRO_cjs.va(e),g=chunkXWSK4QRO_cjs.xa(e),z=chunkXWSK4QRO_cjs.ua(e),F=chunkXWSK4QRO_cjs.ma(e),v=chunkXWSK4QRO_cjs.Oa(e),C=chunkXWSK4QRO_cjs.Pa(e);return {element:e,htmlPreview:g,stackContext:t,componentName:z,fiber:F,selector:v,styles:C}},r=new Set,n=false,R=e=>{n=true,chunkXWSK4QRO_cjs.za(),r.add(chunkXWSK4QRO_cjs.Ba(e??[document.body])),chunkXWSK4QRO_cjs.Ca(),chunkXWSK4QRO_cjs.Ma();},D=()=>{n=false;for(let e of Array.from(r))e();r.clear(),chunkXWSK4QRO_cjs.Ba([]),chunkXWSK4QRO_cjs.Da(),chunkXWSK4QRO_cjs.Na();},I=()=>n,L=async(e,t)=>{await chunkXWSK4QRO_cjs.ya(e,t);};exports.freeze=R;exports.getElementContext=H;exports.isFreezeActive=I;exports.openFile=L;exports.unfreeze=D;
@@ -0,0 +1,62 @@
1
+ import { Fiber } from 'bippy';
2
+
3
+ interface ReactGrabElementContext {
4
+ element: Element;
5
+ htmlPreview: string;
6
+ stackContext: string;
7
+ componentName: string | null;
8
+ fiber: Fiber | null;
9
+ selector: string | null;
10
+ styles: string;
11
+ }
12
+ /**
13
+ * Gathers comprehensive context for a DOM element, including its React fiber,
14
+ * component name, source stack, HTML preview, CSS selector, and computed styles.
15
+ *
16
+ * @example
17
+ * const context = await getElementContext(document.querySelector('.my-button')!);
18
+ * console.log(context.componentName); // "SubmitButton"
19
+ * console.log(context.selector); // "button.my-button"
20
+ * console.log(context.stackContext); // "SubmitButton > Form > App"
21
+ */
22
+ declare const getElementContext: (element: Element) => Promise<ReactGrabElementContext>;
23
+ /**
24
+ * Freezes the page by halting React updates, pausing CSS/JS animations,
25
+ * and preserving pseudo-states (e.g. :hover, :focus) on the given elements.
26
+ *
27
+ * @example
28
+ * freeze(); // freezes the entire page
29
+ * freeze([document.querySelector('.modal')!]); // freezes only the modal subtree
30
+ */
31
+ declare const freeze: (elements?: Element[]) => void;
32
+ /**
33
+ * Restores normal page behavior by re-enabling React updates, resuming
34
+ * animations, and releasing preserved pseudo-states.
35
+ *
36
+ * @example
37
+ * freeze();
38
+ * // ... capture a snapshot ...
39
+ * unfreeze(); // page resumes normal behavior
40
+ */
41
+ declare const unfreeze: () => void;
42
+ /**
43
+ * Returns whether the page is currently in a frozen state.
44
+ *
45
+ * @example
46
+ * if (isFreezeActive()) {
47
+ * console.log('Page is frozen, skipping update');
48
+ * }
49
+ */
50
+ declare const isFreezeActive: () => boolean;
51
+ /**
52
+ * Opens the source file at the given path in the user's editor.
53
+ * Tries the dev-server endpoint first (Vite / Next.js), then falls back
54
+ * to a protocol URL (e.g. vscode://file/…).
55
+ *
56
+ * @example
57
+ * openFile("/src/components/Button.tsx");
58
+ * openFile("/src/components/Button.tsx", 42);
59
+ */
60
+ declare const openFile: (filePath: string, lineNumber?: number) => Promise<void>;
61
+
62
+ export { type ReactGrabElementContext, freeze, getElementContext, isFreezeActive, openFile, unfreeze };
@@ -0,0 +1,62 @@
1
+ import { Fiber } from 'bippy';
2
+
3
+ interface ReactGrabElementContext {
4
+ element: Element;
5
+ htmlPreview: string;
6
+ stackContext: string;
7
+ componentName: string | null;
8
+ fiber: Fiber | null;
9
+ selector: string | null;
10
+ styles: string;
11
+ }
12
+ /**
13
+ * Gathers comprehensive context for a DOM element, including its React fiber,
14
+ * component name, source stack, HTML preview, CSS selector, and computed styles.
15
+ *
16
+ * @example
17
+ * const context = await getElementContext(document.querySelector('.my-button')!);
18
+ * console.log(context.componentName); // "SubmitButton"
19
+ * console.log(context.selector); // "button.my-button"
20
+ * console.log(context.stackContext); // "SubmitButton > Form > App"
21
+ */
22
+ declare const getElementContext: (element: Element) => Promise<ReactGrabElementContext>;
23
+ /**
24
+ * Freezes the page by halting React updates, pausing CSS/JS animations,
25
+ * and preserving pseudo-states (e.g. :hover, :focus) on the given elements.
26
+ *
27
+ * @example
28
+ * freeze(); // freezes the entire page
29
+ * freeze([document.querySelector('.modal')!]); // freezes only the modal subtree
30
+ */
31
+ declare const freeze: (elements?: Element[]) => void;
32
+ /**
33
+ * Restores normal page behavior by re-enabling React updates, resuming
34
+ * animations, and releasing preserved pseudo-states.
35
+ *
36
+ * @example
37
+ * freeze();
38
+ * // ... capture a snapshot ...
39
+ * unfreeze(); // page resumes normal behavior
40
+ */
41
+ declare const unfreeze: () => void;
42
+ /**
43
+ * Returns whether the page is currently in a frozen state.
44
+ *
45
+ * @example
46
+ * if (isFreezeActive()) {
47
+ * console.log('Page is frozen, skipping update');
48
+ * }
49
+ */
50
+ declare const isFreezeActive: () => boolean;
51
+ /**
52
+ * Opens the source file at the given path in the user's editor.
53
+ * Tries the dev-server endpoint first (Vite / Next.js), then falls back
54
+ * to a protocol URL (e.g. vscode://file/…).
55
+ *
56
+ * @example
57
+ * openFile("/src/components/Button.tsx");
58
+ * openFile("/src/components/Button.tsx", 42);
59
+ */
60
+ declare const openFile: (filePath: string, lineNumber?: number) => Promise<void>;
61
+
62
+ export { type ReactGrabElementContext, freeze, getElementContext, isFreezeActive, openFile, unfreeze };
@@ -0,0 +1,9 @@
1
+ import {va,xa,ua,ma,Oa,Pa,za,Ba,Ca,Ma,Da,Na,ya}from'./chunk-UERZTOK6.js';/**
2
+ * @license MIT
3
+ *
4
+ * Copyright (c) 2025 Aiden Bai
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+ var H=async e=>{let t=await va(e),g=xa(e),z=ua(e),F=ma(e),v=Oa(e),C=Pa(e);return {element:e,htmlPreview:g,stackContext:t,componentName:z,fiber:F,selector:v,styles:C}},r=new Set,n=false,R=e=>{n=true,za(),r.add(Ba(e??[document.body])),Ca(),Ma();},D=()=>{n=false;for(let e of Array.from(r))e();r.clear(),Ba([]),Da(),Na();},I=()=>n,L=async(e,t)=>{await ya(e,t);};export{R as freeze,H as getElementContext,I as isFreezeActive,L as openFile,D as unfreeze};
package/dist/react.cjs CHANGED
@@ -2152,7 +2152,7 @@ var VERSION, VIEWPORT_MARGIN_PX, OFFSCREEN_POSITION, SELECTION_LERP_FACTOR, FEED
2152
2152
  var init_constants = __esm({
2153
2153
  "src/constants.ts"() {
2154
2154
  "use strict";
2155
- VERSION = "0.1.22";
2155
+ VERSION = "0.1.24";
2156
2156
  VIEWPORT_MARGIN_PX = 8;
2157
2157
  OFFSCREEN_POSITION = -1e3;
2158
2158
  SELECTION_LERP_FACTOR = 0.95;
@@ -2799,6 +2799,7 @@ var init_store2 = __esm({
2799
2799
  if (store.current.state === "justCopied") {
2800
2800
  const shouldReturnToActive = store.current.wasActive && !store.wasActivatedByToggle;
2801
2801
  if (shouldReturnToActive) {
2802
+ actions.clearFrozenElement();
2802
2803
  setStore("current", {
2803
2804
  state: "active",
2804
2805
  phase: "hovering",
@@ -4746,13 +4747,6 @@ var init_overlay_canvas = __esm({
4746
4747
  initializeCanvas();
4747
4748
  scheduleAnimationFrame();
4748
4749
  };
4749
- createEffect(on(() => [props.mouseX, props.mouseY], ([mouseX, mouseY]) => {
4750
- const targetX = mouseX ?? 0;
4751
- const targetY = mouseY ?? 0;
4752
- crosshairCurrentPosition.x = targetX;
4753
- crosshairCurrentPosition.y = targetY;
4754
- scheduleAnimationFrame();
4755
- }));
4756
4750
  createEffect(on(() => props.crosshairVisible, () => {
4757
4751
  scheduleAnimationFrame();
4758
4752
  }));
@@ -4877,6 +4871,15 @@ var init_overlay_canvas = __esm({
4877
4871
  onMount(() => {
4878
4872
  initializeCanvas();
4879
4873
  scheduleAnimationFrame();
4874
+ const handlePointerMove = (event) => {
4875
+ if (!event.isPrimary) return;
4876
+ crosshairCurrentPosition.x = event.clientX;
4877
+ crosshairCurrentPosition.y = event.clientY;
4878
+ scheduleAnimationFrame();
4879
+ };
4880
+ window.addEventListener("pointermove", handlePointerMove, {
4881
+ passive: true
4882
+ });
4880
4883
  window.addEventListener("resize", handleWindowResize);
4881
4884
  let currentDprMediaQuery = null;
4882
4885
  const handleDevicePixelRatioChange = () => {
@@ -4895,6 +4898,7 @@ var init_overlay_canvas = __esm({
4895
4898
  };
4896
4899
  setupDprMediaQuery();
4897
4900
  onCleanup(() => {
4901
+ window.removeEventListener("pointermove", handlePointerMove);
4898
4902
  window.removeEventListener("resize", handleWindowResize);
4899
4903
  if (currentDprMediaQuery) {
4900
4904
  currentDprMediaQuery.removeEventListener("change", handleDevicePixelRatioChange);
@@ -13021,12 +13025,6 @@ var init_renderer = __esm({
13021
13025
  get crosshairVisible() {
13022
13026
  return props.crosshairVisible;
13023
13027
  },
13024
- get mouseX() {
13025
- return props.mouseX;
13026
- },
13027
- get mouseY() {
13028
- return props.mouseY;
13029
- },
13030
13028
  get selectionVisible() {
13031
13029
  return props.selectionVisible;
13032
13030
  },
@@ -15458,7 +15456,7 @@ var init_log_intro = __esm({
15458
15456
  init_is_extension_context();
15459
15457
  logIntro = () => {
15460
15458
  try {
15461
- const version = "0.1.22";
15459
+ const version = "0.1.24";
15462
15460
  const logoDataUri = `data:image/svg+xml;base64,${btoa(LOGO_SVG)}`;
15463
15461
  console.log(
15464
15462
  `%cReact Grab${version ? ` v${version}` : ""}%c
package/dist/react.js CHANGED
@@ -2140,7 +2140,7 @@ var VERSION, VIEWPORT_MARGIN_PX, OFFSCREEN_POSITION, SELECTION_LERP_FACTOR, FEED
2140
2140
  var init_constants = __esm({
2141
2141
  "src/constants.ts"() {
2142
2142
  "use strict";
2143
- VERSION = "0.1.22";
2143
+ VERSION = "0.1.24";
2144
2144
  VIEWPORT_MARGIN_PX = 8;
2145
2145
  OFFSCREEN_POSITION = -1e3;
2146
2146
  SELECTION_LERP_FACTOR = 0.95;
@@ -2787,6 +2787,7 @@ var init_store2 = __esm({
2787
2787
  if (store.current.state === "justCopied") {
2788
2788
  const shouldReturnToActive = store.current.wasActive && !store.wasActivatedByToggle;
2789
2789
  if (shouldReturnToActive) {
2790
+ actions.clearFrozenElement();
2790
2791
  setStore("current", {
2791
2792
  state: "active",
2792
2793
  phase: "hovering",
@@ -4734,13 +4735,6 @@ var init_overlay_canvas = __esm({
4734
4735
  initializeCanvas();
4735
4736
  scheduleAnimationFrame();
4736
4737
  };
4737
- createEffect(on(() => [props.mouseX, props.mouseY], ([mouseX, mouseY]) => {
4738
- const targetX = mouseX ?? 0;
4739
- const targetY = mouseY ?? 0;
4740
- crosshairCurrentPosition.x = targetX;
4741
- crosshairCurrentPosition.y = targetY;
4742
- scheduleAnimationFrame();
4743
- }));
4744
4738
  createEffect(on(() => props.crosshairVisible, () => {
4745
4739
  scheduleAnimationFrame();
4746
4740
  }));
@@ -4865,6 +4859,15 @@ var init_overlay_canvas = __esm({
4865
4859
  onMount(() => {
4866
4860
  initializeCanvas();
4867
4861
  scheduleAnimationFrame();
4862
+ const handlePointerMove = (event) => {
4863
+ if (!event.isPrimary) return;
4864
+ crosshairCurrentPosition.x = event.clientX;
4865
+ crosshairCurrentPosition.y = event.clientY;
4866
+ scheduleAnimationFrame();
4867
+ };
4868
+ window.addEventListener("pointermove", handlePointerMove, {
4869
+ passive: true
4870
+ });
4868
4871
  window.addEventListener("resize", handleWindowResize);
4869
4872
  let currentDprMediaQuery = null;
4870
4873
  const handleDevicePixelRatioChange = () => {
@@ -4883,6 +4886,7 @@ var init_overlay_canvas = __esm({
4883
4886
  };
4884
4887
  setupDprMediaQuery();
4885
4888
  onCleanup(() => {
4889
+ window.removeEventListener("pointermove", handlePointerMove);
4886
4890
  window.removeEventListener("resize", handleWindowResize);
4887
4891
  if (currentDprMediaQuery) {
4888
4892
  currentDprMediaQuery.removeEventListener("change", handleDevicePixelRatioChange);
@@ -13009,12 +13013,6 @@ var init_renderer = __esm({
13009
13013
  get crosshairVisible() {
13010
13014
  return props.crosshairVisible;
13011
13015
  },
13012
- get mouseX() {
13013
- return props.mouseX;
13014
- },
13015
- get mouseY() {
13016
- return props.mouseY;
13017
- },
13018
13016
  get selectionVisible() {
13019
13017
  return props.selectionVisible;
13020
13018
  },
@@ -15446,7 +15444,7 @@ var init_log_intro = __esm({
15446
15444
  init_is_extension_context();
15447
15445
  logIntro = () => {
15448
15446
  try {
15449
- const version = "0.1.22";
15447
+ const version = "0.1.24";
15450
15448
  const logoDataUri = `data:image/svg+xml;base64,${btoa(LOGO_SVG)}`;
15451
15449
  console.log(
15452
15450
  `%cReact Grab${version ? ` v${version}` : ""}%c
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-grab",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Select context for coding agents directly from your website",
5
5
  "keywords": [
6
6
  "agent",
@@ -22,7 +22,11 @@
22
22
  "type": "git",
23
23
  "url": "git+https://github.com/aidenybai/react-grab.git"
24
24
  },
25
+ "bin": {
26
+ "react-grab": "./bin/cli.js"
27
+ },
25
28
  "files": [
29
+ "bin",
26
30
  "dist",
27
31
  "package.json",
28
32
  "README.md",
@@ -65,6 +69,16 @@
65
69
  "default": "./dist/react.cjs"
66
70
  }
67
71
  },
72
+ "./primitives": {
73
+ "import": {
74
+ "types": "./dist/primitives.d.ts",
75
+ "default": "./dist/primitives.js"
76
+ },
77
+ "require": {
78
+ "types": "./dist/primitives.d.cts",
79
+ "default": "./dist/primitives.cjs"
80
+ }
81
+ },
68
82
  "./src/*": "./src/*",
69
83
  "./styles.css": "./dist/styles.css",
70
84
  "./dist/styles.css": "./dist/styles.css",
@@ -79,7 +93,8 @@
79
93
  "dependencies": {
80
94
  "@medv/finder": "^4.0.2",
81
95
  "bippy": "^0.5.30",
82
- "solid-js": "^1.9.10"
96
+ "solid-js": "^1.9.10",
97
+ "@react-grab/cli": "0.1.24"
83
98
  },
84
99
  "devDependencies": {
85
100
  "@babel/core": "^7.28.5",