grab 0.0.7 → 0.0.77

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/LICENSE CHANGED
@@ -1,19 +1,21 @@
1
- Copyright (c) 2013 Andrew Luetgers,
1
+ MIT License
2
2
 
3
- Permission is hereby granted, free of charge, to any person
4
- obtaining a copy of this software and associated documentation files (the
5
- “Software”), to deal in the Software without restriction, including without
6
- limitation the rights to use, copy, modify, merge, publish, distribute,
7
- sublicense, and/or sell copies of the Software, and to permit persons to whom
8
- the Software is furnished to do so, subject to the following conditions:
3
+ Copyright (c) 2025 Aiden Bai
9
4
 
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
12
11
 
13
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
16
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
17
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,99 +1,334 @@
1
- grab.js
2
- =======
1
+ # <img src="https://github.com/aidenybai/react-grab/blob/main/.github/public/logo.png?raw=true" width="60" align="center" /> Grab
2
+
3
+ [![size](https://img.shields.io/bundlephobia/minzip/grab?label=gzip&style=flat&colorA=000000&colorB=000000)](https://bundlephobia.com/package/grab)
4
+ [![version](https://img.shields.io/npm/v/grab?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/grab)
5
+ [![downloads](https://img.shields.io/npm/dt/grab.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/grab)
6
+
7
+ React Grab allows you to select an element and copy its context (like HTML, React component, and file source)
8
+
9
+ It makes tools like Cursor, Claude Code, Copilot run up to [**66% faster**](https://react-grab.com/blog/intro)
10
+
11
+ ### [Try out a demo! →](https://react-grab.com)
12
+
13
+ https://github.com/user-attachments/assets/fdb34329-b471-4b39-b433-0b1a27a94bd8
14
+
15
+ ## Install
16
+
17
+ > [**Install using Cursor**](https://cursor.com/link/prompt?text=1.+Run+curl+-s+https%3A%2F%2Freact-grab.com%2Fllms.txt+%0A2.+Understand+the+content+and+follow+the+instructions+to+install+React+Grab.%0A3.+Tell+the+user+to+refresh+their+local+app+and+explain+how+to+use+React+Grab)
18
+
19
+ Run this command to install React Grab into your project. Ensure you are running at project root (e.g. where the `next.config.ts` or `vite.config.ts` file is located).
20
+
21
+ ```html
22
+ npx grab@latest init
23
+ ```
24
+
25
+ ## Manual Installation
26
+
27
+ If you're using a React framework or build tool, view instructions below:
28
+
29
+ #### Next.js (App router)
3
30
 
4
- Simplify grabbing values out of complex objects.
31
+ Add this inside of your `app/layout.tsx`:
5
32
 
33
+ ```jsx
34
+ import Script from "next/script";
6
35
 
7
- This is an add-on for for underscore. So in the browser you'll need to load that first
36
+ export default function RootLayout({ children }) {
37
+ return (
38
+ <html>
39
+ <head>
40
+ {/* put this in the <head> */}
41
+ {process.env.NODE_ENV === "development" && (
42
+ <Script
43
+ src="//unpkg.com/grab/dist/index.global.js"
44
+ crossOrigin="anonymous"
45
+ strategy="beforeInteractive"
46
+ />
47
+ )}
48
+ </head>
49
+ <body>{children}</body>
50
+ </html>
51
+ );
52
+ }
53
+ ```
8
54
 
9
- npm module:
55
+ #### Next.js (Pages router)
10
56
 
11
- npm install grab
57
+ Add this into your `pages/_document.tsx`:
12
58
 
13
- when you require the npm module it will augment root._ if it exists or add it if it doesn't
14
-
15
- require("grab");
16
-
17
- Adds just the grab function to underscore
18
-
19
- assume the following object for all examples
20
-
21
- var data = {
22
- stuff: {
23
- music: {
24
- name: "Avicii"
25
- link: "www.avicii.com/"
26
- },
27
- movie: {
28
- name: "Willy Wonka & the Chocolate Factory"
29
- year: "1971",
30
- imdb: "http://www.imdb.com/title/tt0067992/"
31
- }
32
- }
33
- };
34
-
35
-
36
- provide the object and a string representing the path to the value you want
37
-
38
- var music = _.grab(data, "stuff.music.name");
39
- // music == "Avicii"
40
-
41
-
42
- prevents ugly errors when attempting to access a value on undefined
43
-
44
- var game = _.grab(data, "stuff.game.name");
45
- // game == undefined
46
-
47
-
48
- supports default values, if a value is undefined, null or "" the default will be used
49
-
50
- var musicYear = _.grab(data, "stuff.music.year", "--");
51
- // musicYear == "--"
52
-
53
-
54
- supports alternate paths, if one fails it will try the next
55
-
56
- var link = _.grab(data, ["stuff.music.url", "stuff.music.link"]);
57
- // link == "www.avicii.com/"
58
-
59
-
60
- combine multiple paths with a default value
61
-
62
- var link = _.grab(data, ["stuff.blah.broken.url", "stuff.missing.href"], "none");
63
- // link == "none"
64
-
65
-
66
- declare multiple selections in one object
67
-
68
- var items = _.grab(data, {
69
- artist: "stuff.music.name",
70
- movieYear: "stuff.movie.year"
71
- });
72
- // items = {artist: "Avicii", movieYear: "1971"};
73
-
74
-
75
- use an array to include a default value when using the multiple selection syntax
76
-
77
- var items = _.grab(data, {
78
- artist: ["stuff.blah.name", "none"],
79
- movieYear: ["stuff.foo.year", "unknown"]
80
- });
81
- // items = {artist: "none", movieYear: "unknown"};
82
-
83
-
84
- using an array for multiple paths is supported here too
85
-
86
- var items = _.grab(data, {
87
- artist: [["stuff.blah.name", "stuff.music.name"]],
88
- movieYear: [["stuff.foo.year", "stuff.movie.year"]]
89
- });
90
- // items = {artist: "Avicii", movieYear: "1971"};
91
-
92
-
93
- and the above with default values
94
-
95
- var items = _.grab(data, {
96
- artist: [["stuff.blah.name", "stuff.music.missing"], "--"],
97
- movieYear: [["stuff.foo.year", "stuff.movie.broken"], "--"]
98
- });
99
- // items = {artist: "--", movieYear: "--"};
59
+ ```jsx
60
+ import { Html, Head, Main, NextScript } from "next/document";
61
+
62
+ export default function Document() {
63
+ return (
64
+ <Html lang="en">
65
+ <Head>
66
+ {/* put this in the <Head> */}
67
+ {process.env.NODE_ENV === "development" && (
68
+ <Script
69
+ src="//unpkg.com/grab/dist/index.global.js"
70
+ crossOrigin="anonymous"
71
+ strategy="beforeInteractive"
72
+ />
73
+ )}
74
+ </Head>
75
+ <body>
76
+ <Main />
77
+ <NextScript />
78
+ </body>
79
+ </Html>
80
+ );
81
+ }
82
+ ```
83
+
84
+ #### Vite
85
+
86
+ Your `index.html` could look like this:
87
+
88
+ ```html
89
+ <!doctype html>
90
+ <html lang="en">
91
+ <head>
92
+ <script type="module">
93
+ // first npm i grab
94
+ // then in head:
95
+ if (import.meta.env.DEV) {
96
+ import("grab");
97
+ }
98
+ </script>
99
+ </head>
100
+ <body>
101
+ <div id="root"></div>
102
+ <script type="module" src="/src/main.tsx"></script>
103
+ </body>
104
+ </html>
105
+ ```
106
+
107
+ #### Webpack
108
+
109
+ First, install React Grab:
110
+
111
+ ```bash
112
+ npm install grab
113
+ ```
114
+
115
+ Then add this at the top of your main entry file (e.g., `src/index.tsx` or `src/main.tsx`):
116
+
117
+ ```tsx
118
+ if (process.env.NODE_ENV === "development") {
119
+ import("grab");
120
+ }
121
+ ```
122
+
123
+ ## Coding agent integration (beta)
124
+
125
+ React Grab can send selected element context directly to your coding agent. This enables a workflow where you select a UI element and an agent automatically makes changes to your codebase.
126
+
127
+ This means **no copying and pasting** - just select the element and let the agent do the rest. [Learn more →](https://react-grab.com/blog/agent)
128
+
129
+ ### Claude Code
130
+
131
+ #### Server Setup
132
+
133
+ The server runs on port `4567` and interfaces with the Claude Agent SDK. Add to your `package.json`:
134
+
135
+ ```json
136
+ {
137
+ "scripts": {
138
+ "dev": "npx @react-grab/claude-code@latest && next dev"
139
+ }
140
+ }
141
+ ```
142
+
143
+ #### Client Setup
144
+
145
+ ```html
146
+ <script src="//unpkg.com/grab/dist/index.global.js"></script>
147
+ <!-- add this in the <head> -->
148
+ <script src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"></script>
149
+ ```
150
+
151
+ Or using Next.js `Script` component in your `app/layout.tsx`:
152
+
153
+ ```jsx
154
+ import Script from "next/script";
155
+
156
+ export default function RootLayout({ children }) {
157
+ return (
158
+ <html>
159
+ <head>
160
+ {process.env.NODE_ENV === "development" && (
161
+ <>
162
+ <Script
163
+ src="//unpkg.com/grab/dist/index.global.js"
164
+ strategy="beforeInteractive"
165
+ />
166
+ <Script
167
+ src="//unpkg.com/@react-grab/claude-code/dist/client.global.js"
168
+ strategy="lazyOnload"
169
+ />
170
+ </>
171
+ )}
172
+ </head>
173
+ <body>{children}</body>
174
+ </html>
175
+ );
176
+ }
177
+ ```
178
+
179
+ ### Cursor CLI
180
+
181
+ #### Server Setup
182
+
183
+ The server runs on port `5567` and interfaces with the `cursor-agent` CLI. Add to your `package.json`:
184
+
185
+ ```json
186
+ {
187
+ "scripts": {
188
+ "dev": "npx @react-grab/cursor@latest && next dev"
189
+ }
190
+ }
191
+ ```
192
+
193
+ #### Client Setup
194
+
195
+ ```html
196
+ <script src="//unpkg.com/grab/dist/index.global.js"></script>
197
+ <!-- add this in the <head> -->
198
+ <script src="//unpkg.com/@react-grab/cursor/dist/client.global.js"></script>
199
+ ```
200
+
201
+ Or using Next.js `Script` component in your `app/layout.tsx`:
202
+
203
+ ```jsx
204
+ import Script from "next/script";
205
+
206
+ export default function RootLayout({ children }) {
207
+ return (
208
+ <html>
209
+ <head>
210
+ {process.env.NODE_ENV === "development" && (
211
+ <>
212
+ <Script
213
+ src="//unpkg.com/grab/dist/index.global.js"
214
+ strategy="beforeInteractive"
215
+ />
216
+ <Script
217
+ src="//unpkg.com/@react-grab/cursor/dist/client.global.js"
218
+ strategy="lazyOnload"
219
+ />
220
+ </>
221
+ )}
222
+ </head>
223
+ <body>{children}</body>
224
+ </html>
225
+ );
226
+ }
227
+ ```
228
+
229
+ ### Opencode
230
+
231
+ #### Server Setup
232
+
233
+ The server runs on port `6567` and interfaces with the Opencode CLI. Add to your `package.json`:
234
+
235
+ ```json
236
+ {
237
+ "scripts": {
238
+ "dev": "npx @react-grab/opencode@latest && next dev"
239
+ }
240
+ }
241
+ ```
242
+
243
+ > **Note:** You must have [Opencode](https://opencode.ai) installed (`npm i -g opencode-ai@latest`).
244
+
245
+ #### Client Setup
246
+
247
+ ```html
248
+ <script src="//unpkg.com/grab/dist/index.global.js"></script>
249
+ <!-- add this in the <head> -->
250
+ <script src="//unpkg.com/@react-grab/opencode/dist/client.global.js"></script>
251
+ ```
252
+
253
+ Or using Next.js `Script` component in your `app/layout.tsx`:
254
+
255
+ ```jsx
256
+ import Script from "next/script";
257
+
258
+ export default function RootLayout({ children }) {
259
+ return (
260
+ <html>
261
+ <head>
262
+ {process.env.NODE_ENV === "development" && (
263
+ <>
264
+ <Script
265
+ src="//unpkg.com/grab/dist/index.global.js"
266
+ strategy="beforeInteractive"
267
+ />
268
+ <Script
269
+ src="//unpkg.com/@react-grab/opencode/dist/client.global.js"
270
+ strategy="lazyOnload"
271
+ />
272
+ </>
273
+ )}
274
+ </head>
275
+ <body>{children}</body>
276
+ </html>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ## Extending React Grab
282
+
283
+ React Grab provides an public customization API. Check out the [type definitions](https://github.com/aidenybai/react-grab/blob/main/packages/react-grab/src/types.ts) to see all available options for extending React Grab.
284
+
285
+ ```typescript
286
+ import { init } from "grab/core";
287
+
288
+ const api = init({
289
+ theme: {
290
+ enabled: true, // disable all UI by setting to false
291
+ hue: 180, // shift colors by 180 degrees (pink → cyan/turquoise)
292
+ crosshair: {
293
+ enabled: false, // disable crosshair
294
+ },
295
+ elementLabel: {
296
+ enabled: false, // disable element label
297
+ },
298
+ },
299
+
300
+ onElementSelect: (element) => {
301
+ console.log("Selected:", element);
302
+ },
303
+ onCopySuccess: (elements, content) => {
304
+ console.log("Copied to clipboard:", content);
305
+ },
306
+ onStateChange: (state) => {
307
+ console.log("Active:", state.isActive);
308
+ },
309
+ });
310
+
311
+ api.activate();
312
+ api.copyElement(document.querySelector(".my-element"));
313
+ console.log(api.getState());
314
+ ```
315
+
316
+ ## Resources & Contributing Back
317
+
318
+ Want to try it out? Check the [our demo](https://react-grab.com).
319
+
320
+ Looking to contribute back? Check the [Contributing Guide](https://github.com/aidenybai/react-grab/blob/main/CONTRIBUTING.md) out.
321
+
322
+ Want to talk to the community? Hop in our [Discord](https://discord.com/invite/G7zxfUzkm7) and share your ideas and what you've build with React Grab.
323
+
324
+ Find a bug? Head over to our [issue tracker](https://github.com/aidenybai/react-grab/issues) and we'll do our best to help. We love pull requests, too!
325
+
326
+ We expect all contributors to abide by the terms of our [Code of Conduct](https://github.com/aidenybai/react-grab/blob/main/.github/CODE_OF_CONDUCT.md).
327
+
328
+ [**→ Start contributing on GitHub**](https://github.com/aidenybai/react-grab/blob/main/CONTRIBUTING.md)
329
+
330
+ ### License
331
+
332
+ React Grab is MIT-licensed open-source software.
333
+
334
+ _Thank you to [Andrew Luetgers](https://github.com/andrewluetgers) for donating the `grab` npm package name._