@react-spot/core 0.0.1

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 ADDED
@@ -0,0 +1,144 @@
1
+ # @react-spot/core
2
+
3
+ `@react-spot/core` is the low-level package that powers the React Trace inspector widget. It gives you the `Trace` component, the plugin contract, and the hooks/utilities that official and custom plugins use.
4
+
5
+ Use this package when you want to:
6
+
7
+ - Mount the inspector yourself
8
+ - Choose exactly which plugins to enable
9
+ - Build custom plugins against the public core API
10
+
11
+ If you want the batteries-included bundle with all official plugins pre-wired, use `react-trace` instead.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pnpm add --dev @react-spot/core
17
+ ```
18
+
19
+ Peer requirements:
20
+
21
+ - `react >= 18`
22
+ - `react-dom >= 18`
23
+
24
+ ## Minimal usage
25
+
26
+ Change your dev script to export the project root e.g.:
27
+
28
+ ```diff
29
+ - "dev": "vite"
30
+ + "dev": "VITE_ROOT=$(pwd) vite",
31
+ ```
32
+
33
+ Then add it next to your app:
34
+
35
+ ```tsx
36
+ import { Trace } from '@react-spot/core'
37
+
38
+ import App from './App'
39
+
40
+ export function Root() {
41
+ return (
42
+ <>
43
+ <App />
44
+ <Trace root={import.meta.env.VITE_ROOT} />
45
+ </>
46
+ )
47
+ }
48
+ ```
49
+
50
+ `root` must be the absolute path to the project being inspected.
51
+
52
+ ## When to use `@react-spot/core` vs `react-trace`
53
+
54
+ - Use `@react-spot/core` when you want a custom plugin list or your own plugins.
55
+ - Use `react-trace` when you want the default bundle of official plugins (`preview`, `copy-to-clipboard`, `open-editor`, and `comments`) with one import.
56
+
57
+ ## `Trace` component
58
+
59
+ `Trace` is the widget entrypoint exported by this package.
60
+
61
+ ### Props
62
+
63
+ - `root: string` — absolute project root path
64
+ - `plugins?: TracePlugin[]` — plugin instances to mount
65
+ - `position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'` — initial toolbar position
66
+ - `minimized?: boolean` — whether the widget starts minimized by default
67
+
68
+ ## Plugin model
69
+
70
+ Plugins implement `TracePlugin`:
71
+
72
+ ```ts
73
+ interface TracePlugin {
74
+ name: string
75
+ toolbar?: ComponentType
76
+ actionPanel?: ComponentType
77
+ settings?: ComponentType
78
+ }
79
+ ```
80
+
81
+ - `toolbar` renders inside the widget toolbar.
82
+ - `actionPanel` renders inside the selected-component action menu.
83
+ - `settings` renders inside the widget settings popover.
84
+
85
+ Plugin-owned components receive no props. Read shared widget state through the exported hooks instead.
86
+
87
+ ### Minimal plugin example
88
+
89
+ > Tip: Run `pnpm create react-trace-plugin` to scaffold a full plugin package with build config and production stubs.
90
+
91
+ ```tsx
92
+ import {
93
+ Trace,
94
+ useSelectedContext,
95
+ type TracePlugin,
96
+ } from '@react-spot/core'
97
+
98
+ function SelectionInfo() {
99
+ const context = useSelectedContext()
100
+ return context ? <button type="button">{context.displayName}</button> : null
101
+ }
102
+
103
+ const examplePlugin: TracePlugin = {
104
+ name: 'Example',
105
+ toolbar: SelectionInfo,
106
+ }
107
+
108
+ export function AppShell() {
109
+ return <Trace root="/absolute/path/to/project" plugins={[examplePlugin]} />
110
+ }
111
+ ```
112
+
113
+ ## Exported hooks
114
+
115
+ - `useProjectRoot()` — returns the current project root string
116
+ - `useInspectorActive()` — returns whether inspector mode is active
117
+ - `useDeactivateInspector()` — returns a callback that turns inspector mode off
118
+ - `useSelectedContext()` — returns the currently selected `ComponentContext | null`
119
+ - `useClearSelectedContext()` — returns a callback that clears the current selection
120
+ - `useSelectedSource()` — returns the currently selected `ComponentSource | null`
121
+ - `useWidgetPortalContainer()` — returns the widget portal container element
122
+
123
+ ## Exported utilities and constants
124
+
125
+ - `settingsPluginAtom(pluginKey)` — returns a writable Jotai atom for a section of `TraceSettings`
126
+ - `IS_MAC` — `true` on macOS/iOS user agents
127
+ - `MOD_KEY` — platform-specific modifier key label (`⌘` or `Ctrl`)
128
+
129
+ ## Exported types
130
+
131
+ - `ComponentContext` — full context of an inspected component (element, name, breadcrumb, props, sources)
132
+ - `ComponentSource` — source file location (`fileName`, `lineNumber`, `columnNumber`, `relativePath`, `absolutePath`)
133
+ - `TracePlugin`
134
+ - `TraceProps`
135
+ - `TraceSettings`
136
+
137
+ ## Notes for plugin authors
138
+
139
+ - `useWidgetPortalContainer()` lets plugin popovers, tooltips, and menus render inside the widget portal instead of `document.body`.
140
+ - `settingsPluginAtom()` is keyed by `TraceSettings`, so plugin settings should live under a stable top-level key.
141
+
142
+ ## Production builds
143
+
144
+ This package publishes development and production entrypoints. In production mode, the exported `Trace` component resolves to a no-op stub, which keeps the inspector at zero runtime cost when production export conditions are used.
@@ -0,0 +1,36 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) {
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ }
14
+ if (!no_symbols) {
15
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
16
+ }
17
+ return target;
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
22
+ key = keys[i];
23
+ if (!__hasOwnProp.call(to, key) && key !== except) {
24
+ __defProp(to, key, {
25
+ get: ((k) => from[k]).bind(null, key),
26
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
27
+ });
28
+ }
29
+ }
30
+ }
31
+ return to;
32
+ };
33
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
34
+
35
+ //#endregion
36
+ export { __reExport as n, __exportAll as t };
@@ -0,0 +1,67 @@
1
+ import { ComponentType } from "react";
2
+
3
+ //#region src/types.d.ts
4
+ type EditorPreset = 'vscode' | 'cursor' | 'windsurf' | 'webstorm' | 'intellij' | 'zed';
5
+ interface ComponentSource {
6
+ fileName: string;
7
+ lineNumber: number;
8
+ columnNumber: number;
9
+ /** Path relative to the project root, e.g. "src/App.tsx" */
10
+ relativePath: string;
11
+ /** Absolute filesystem path, e.g. "/Users/you/project/src/App.tsx" */
12
+ absolutePath: string;
13
+ }
14
+ interface ComponentContext {
15
+ element: HTMLElement;
16
+ displayName: string;
17
+ /** e.g. ['Card', 'p', 'code'] — nearest React component down to the hovered DOM element */
18
+ breadcrumb: string[];
19
+ all: Array<{
20
+ source: ComponentSource | null;
21
+ names: string[];
22
+ }>;
23
+ props: Record<string, unknown>;
24
+ }
25
+ interface TracePlugin {
26
+ name: string;
27
+ /**
28
+ * Component to render inside the widget's toolbar.
29
+ */
30
+ toolbar?: ComponentType;
31
+ /**
32
+ * Component to render inside the settings dropdown.
33
+ */
34
+ settings?: ComponentType;
35
+ }
36
+ type WidgetPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
37
+ interface TraceProps {
38
+ /**
39
+ * Absolute path to the project root, forwarded to all plugins
40
+ */
41
+ root: string;
42
+ /**
43
+ * Editor to open files in when clicking a component.
44
+ * @default 'vscode'
45
+ */
46
+ editor?: EditorPreset;
47
+ plugins?: TracePlugin[];
48
+ position?: WidgetPosition;
49
+ minimized?: boolean;
50
+ }
51
+ interface TraceSettings {
52
+ core: {
53
+ position: WidgetPosition;
54
+ minimized: boolean;
55
+ };
56
+ }
57
+ //#endregion
58
+ //#region src/utils/platform.d.ts
59
+ /** True when running on macOS / iOS */
60
+ declare const IS_MAC: boolean;
61
+ /** The modifier key label for the current platform */
62
+ declare const MOD_KEY: string;
63
+ import * as import_jotai_vanilla from "jotai/vanilla";
64
+ import * as import_jotai_react from "jotai/react";
65
+ //#endregion
66
+ export { ComponentSource as a, TraceProps as c, ComponentContext as i, TraceSettings as l, IS_MAC as n, EditorPreset as o, MOD_KEY as r, TracePlugin as s, index_d_exports as t };
67
+ //# sourceMappingURL=index-CyjjTUAd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-CyjjTUAd.d.ts","names":[],"sources":["../src/types.ts","../src/utils/platform.ts","../../../node_modules/.pnpm/jotai@2.18.0_@babel+core@7.29.0_@babel+template@7.28.6_@types+react@19.2.14_react@19.2.4/node_modules/jotai/esm/index.d.mts"],"x_google_ignoreList":[2],"mappings":";;;KAEY,YAAA;AAAA,UAQK,eAAA;EACf,QAAA;EACA,UAAA;EACA,YAAA;;EAEA,YAAA;EAbsB;EAetB,YAAA;AAAA;AAAA,UAGe,gBAAA;EACf,OAAA,EAAS,WAAA;EACT,WAAA;EAVA;EAYA,UAAA;EACA,GAAA,EAAK,KAAA;IAAQ,MAAA,EAAQ,eAAA;IAAwB,KAAA;EAAA;EAC7C,KAAA,EAAO,MAAA;AAAA;AAAA,UAGQ,WAAA;EACf,IAAA;EALqB;;;EASrB,OAAA,GAAU,aAAA;EARG;;;EAYb,QAAA,GAAW,aAAA;AAAA;AAAA,KAGR,cAAA;AAAA,UAEY,UAAA;EAlBF;;;EAsBb,IAAA;EArBO;;;AAGT;EAuBE,MAAA,GAAS,YAAA;EACT,OAAA,GAAU,WAAA;EACV,QAAA,GAAW,cAAA;EACX,SAAA;AAAA;AAAA,UAGe,aAAA;EACf,IAAA;IACE,QAAA,EAAU,cAAA;IACV,SAAA;EAAA;AAAA;;;;cC5DS,MAAA;;cAKA,OAAA"}
@@ -0,0 +1,69 @@
1
+ import { ComponentType } from "react";
2
+
3
+ //#region \0rolldown/runtime.js
4
+ //#endregion
5
+ //#region src/types.d.ts
6
+ type EditorPreset = 'vscode' | 'cursor' | 'windsurf' | 'webstorm' | 'intellij' | 'zed';
7
+ interface ComponentSource {
8
+ fileName: string;
9
+ lineNumber: number;
10
+ columnNumber: number;
11
+ /** Path relative to the project root, e.g. "src/App.tsx" */
12
+ relativePath: string;
13
+ /** Absolute filesystem path, e.g. "/Users/you/project/src/App.tsx" */
14
+ absolutePath: string;
15
+ }
16
+ interface ComponentContext {
17
+ element: HTMLElement;
18
+ displayName: string;
19
+ /** e.g. ['Card', 'p', 'code'] — nearest React component down to the hovered DOM element */
20
+ breadcrumb: string[];
21
+ all: Array<{
22
+ source: ComponentSource | null;
23
+ names: string[];
24
+ }>;
25
+ props: Record<string, unknown>;
26
+ }
27
+ interface TracePlugin {
28
+ name: string;
29
+ /**
30
+ * Component to render inside the widget's toolbar.
31
+ */
32
+ toolbar?: ComponentType;
33
+ /**
34
+ * Component to render inside the settings dropdown.
35
+ */
36
+ settings?: ComponentType;
37
+ }
38
+ type WidgetPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
39
+ interface TraceProps {
40
+ /**
41
+ * Absolute path to the project root, forwarded to all plugins
42
+ */
43
+ root: string;
44
+ /**
45
+ * Editor to open files in when clicking a component.
46
+ * @default 'vscode'
47
+ */
48
+ editor?: EditorPreset;
49
+ plugins?: TracePlugin[];
50
+ position?: WidgetPosition;
51
+ minimized?: boolean;
52
+ }
53
+ interface TraceSettings {
54
+ core: {
55
+ position: WidgetPosition;
56
+ minimized: boolean;
57
+ };
58
+ }
59
+ //#endregion
60
+ //#region src/utils/platform.d.ts
61
+ /** True when running on macOS / iOS */
62
+ declare const IS_MAC: boolean;
63
+ /** The modifier key label for the current platform */
64
+ declare const MOD_KEY: string;
65
+ import * as import_jotai_vanilla from "jotai/vanilla";
66
+ import * as import_jotai_react from "jotai/react";
67
+ //#endregion
68
+ export { ComponentSource as a, TraceProps as c, ComponentContext as i, TraceSettings as l, IS_MAC as n, EditorPreset as o, MOD_KEY as r, TracePlugin as s, index_d_exports as t };
69
+ //# sourceMappingURL=index-ujwIx3_4.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-ujwIx3_4.d.cts","names":[],"sources":["../src/types.ts","../src/utils/platform.ts","../../../node_modules/.pnpm/jotai@2.18.0_@babel+core@7.29.0_@babel+template@7.28.6_@types+react@19.2.14_react@19.2.4/node_modules/jotai/esm/index.d.mts"],"x_google_ignoreList":[2],"mappings":";;;;;KAEY,YAAA;AAAA,UAQK,eAAA;EACf,QAAA;EACA,UAAA;EACA,YAAA;;EAEA,YAAA;;EAEA,YAAA;AAAA;AAAA,UAGe,gBAAA;EACf,OAAA,EAAS,WAAA;EACT,WAAA;;EAEA,UAAA;EACA,GAAA,EAAK,KAAA;IAAQ,MAAA,EAAQ,eAAA;IAAwB,KAAA;EAAA;EAC7C,KAAA,EAAO,MAAA;AAAA;AAAA,UAGQ,WAAA;EACf,IAAA;;;;EAIA,OAAA,GAAU,aAAA;;;;EAIV,QAAA,GAAW,aAAA;AAAA;AAAA,KAGR,cAAA;AAAA,UAEY,UAAA;;;;EAIf,IAAA;EA7CsB;;;;EAkDtB,MAAA,GAAS,YAAA;EACT,OAAA,GAAU,WAAA;EACV,QAAA,GAAW,cAAA;EACX,SAAA;AAAA;AAAA,UAGe,aAAA;EACf,IAAA;IACE,QAAA,EAAU,cAAA;IACV,SAAA;EAAA;AAAA;;;;cC5DS,MAAA;;cAKA,OAAA"}