@paramour-js/devtools-panel 0.6.0

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/styles.js ADDED
@@ -0,0 +1,278 @@
1
+ /**
2
+ * The panel's entire stylesheet, rendered as an inline `<style>` element by
3
+ * the panel root — no stylesheet import, no CSS-in-JS dependency, zero
4
+ * runtime deps. All selectors are `.pmr-` prefixed, so duplicate injection
5
+ * (two panels) is harmless. CSP note: an inline `<style>` needs
6
+ * `style-src 'unsafe-inline'` or a nonce — acceptable for a dev-only tool,
7
+ * documented rather than solved in v1.
8
+ *
9
+ * Theming: the shell's `theme` prop lands as a `data-theme` attribute on
10
+ * `.pmr-root`; the custom-property token set below flips with it — no theme
11
+ * context, no remount. Violet/indigo accent is paramour's own; the four
12
+ * status colors follow devtool traffic-light convention. Density and the
13
+ * monospace wire stack keep the tables scannable; the only motion is the
14
+ * ~400ms row flash plus the copy-button glyph swap.
15
+ */
16
+ export const PANEL_CSS = `
17
+ .pmr-root {
18
+ --pmr-accent: #6d5ae6;
19
+ --pmr-accent-soft: #6d5ae62e;
20
+ --pmr-bg: #ffffff;
21
+ --pmr-bg-raised: #f6f5fb;
22
+ --pmr-border: #e2e0ef;
23
+ --pmr-flash-duration: 400ms;
24
+ --pmr-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
25
+ --pmr-font-ui: system-ui, -apple-system, "Segoe UI", sans-serif;
26
+ --pmr-status-error: #e5484d;
27
+ --pmr-status-ok: #30a46c;
28
+ --pmr-status-pending: #f5a524;
29
+ --pmr-status-stale: #8f8f8f;
30
+ --pmr-text: #232130;
31
+ --pmr-text-muted: #6f6c85;
32
+
33
+ background: var(--pmr-bg);
34
+ color: var(--pmr-text);
35
+ display: flex;
36
+ font-family: var(--pmr-font-ui);
37
+ font-size: 12px;
38
+ height: 100%;
39
+ line-height: 1.45;
40
+ min-height: 0;
41
+ overflow: hidden;
42
+ width: 100%;
43
+ }
44
+ .pmr-root[data-theme="dark"] {
45
+ --pmr-accent: #8b7cf0;
46
+ --pmr-accent-soft: #8b7cf03d;
47
+ --pmr-bg: #17151f;
48
+ --pmr-bg-raised: #201d2b;
49
+ --pmr-border: #322e42;
50
+ --pmr-status-error: #ff6369;
51
+ --pmr-status-ok: #3dd68c;
52
+ --pmr-status-pending: #ffb224;
53
+ --pmr-status-stale: #7c7c7c;
54
+ --pmr-text: #eceaf4;
55
+ --pmr-text-muted: #9b97ad;
56
+ }
57
+
58
+ .pmr-sidebar {
59
+ border-right: 1px solid var(--pmr-border);
60
+ flex: 0 0 190px;
61
+ overflow-y: auto;
62
+ padding: 6px 0;
63
+ }
64
+ .pmr-sidebar-entry {
65
+ align-items: center;
66
+ background: none;
67
+ border: none;
68
+ color: var(--pmr-text);
69
+ cursor: pointer;
70
+ display: flex;
71
+ font: inherit;
72
+ gap: 6px;
73
+ padding: 4px 10px;
74
+ text-align: left;
75
+ width: 100%;
76
+ }
77
+ .pmr-sidebar-entry:hover {
78
+ background: var(--pmr-bg-raised);
79
+ }
80
+ .pmr-sidebar-entry[data-selected="true"] {
81
+ background: var(--pmr-accent-soft);
82
+ }
83
+ .pmr-sidebar-entry[data-stale="true"] {
84
+ opacity: 0.55;
85
+ }
86
+ .pmr-sidebar-path {
87
+ font-family: var(--pmr-font-mono);
88
+ overflow: hidden;
89
+ text-overflow: ellipsis;
90
+ white-space: nowrap;
91
+ }
92
+
93
+ .pmr-main {
94
+ flex: 1 1 auto;
95
+ min-width: 0;
96
+ overflow-y: auto;
97
+ padding: 8px 12px 16px;
98
+ }
99
+
100
+ .pmr-banner {
101
+ align-items: center;
102
+ background: var(--pmr-bg-raised);
103
+ border: 1px solid var(--pmr-border);
104
+ border-radius: 6px;
105
+ display: flex;
106
+ gap: 8px;
107
+ margin: 8px 0 6px;
108
+ padding: 6px 10px;
109
+ }
110
+ .pmr-banner-path {
111
+ font-family: var(--pmr-font-mono);
112
+ font-size: 13px;
113
+ font-weight: 600;
114
+ }
115
+ .pmr-badge {
116
+ border: 1px solid var(--pmr-border);
117
+ border-radius: 999px;
118
+ color: var(--pmr-text-muted);
119
+ font-size: 10px;
120
+ padding: 0 6px;
121
+ text-transform: uppercase;
122
+ }
123
+ .pmr-stale-badge {
124
+ color: var(--pmr-status-stale);
125
+ font-size: 10px;
126
+ text-transform: uppercase;
127
+ }
128
+
129
+ .pmr-dot {
130
+ align-items: center;
131
+ display: inline-flex;
132
+ flex: none;
133
+ gap: 3px;
134
+ }
135
+ .pmr-dot::before {
136
+ border-radius: 50%;
137
+ content: "";
138
+ display: inline-block;
139
+ height: 8px;
140
+ width: 8px;
141
+ }
142
+ .pmr-dot--error::before { background: var(--pmr-status-error); }
143
+ .pmr-dot--ok::before { background: var(--pmr-status-ok); }
144
+ .pmr-dot--pending::before { background: var(--pmr-status-pending); }
145
+ .pmr-dot--stale::before { background: var(--pmr-status-stale); }
146
+ .pmr-dot-glyph {
147
+ font-size: 10px;
148
+ }
149
+ .pmr-dot--error .pmr-dot-glyph { color: var(--pmr-status-error); }
150
+ .pmr-dot--ok .pmr-dot-glyph { color: var(--pmr-status-ok); }
151
+ .pmr-dot--pending .pmr-dot-glyph { color: var(--pmr-status-pending); }
152
+ .pmr-dot--stale .pmr-dot-glyph { color: var(--pmr-status-stale); }
153
+
154
+ .pmr-section-title {
155
+ color: var(--pmr-text-muted);
156
+ font-size: 10px;
157
+ font-weight: 600;
158
+ letter-spacing: 0.08em;
159
+ margin: 10px 0 2px;
160
+ text-transform: uppercase;
161
+ }
162
+ .pmr-table {
163
+ border-collapse: collapse;
164
+ width: 100%;
165
+ }
166
+ .pmr-table th {
167
+ border-bottom: 1px solid var(--pmr-border);
168
+ color: var(--pmr-text-muted);
169
+ font-size: 10px;
170
+ font-weight: 600;
171
+ padding: 2px 8px 2px 0;
172
+ text-align: left;
173
+ text-transform: uppercase;
174
+ }
175
+ .pmr-table td {
176
+ border-bottom: 1px solid var(--pmr-border);
177
+ height: 22px;
178
+ padding: 2px 8px 2px 0;
179
+ vertical-align: middle;
180
+ }
181
+ .pmr-mono {
182
+ font-family: var(--pmr-font-mono);
183
+ }
184
+ .pmr-muted {
185
+ color: var(--pmr-text-muted);
186
+ }
187
+ @keyframes pmr-flash {
188
+ from { background-color: var(--pmr-accent-soft); }
189
+ to { background-color: transparent; }
190
+ }
191
+ .pmr-flash {
192
+ animation: pmr-flash var(--pmr-flash-duration) ease-out;
193
+ }
194
+ .pmr-tag {
195
+ border: 1px solid var(--pmr-border);
196
+ border-radius: 3px;
197
+ color: var(--pmr-text-muted);
198
+ font-size: 10px;
199
+ padding: 0 4px;
200
+ }
201
+
202
+ .pmr-input,
203
+ .pmr-select,
204
+ .pmr-textarea {
205
+ background: var(--pmr-bg);
206
+ border: 1px solid var(--pmr-border);
207
+ border-radius: 4px;
208
+ color: var(--pmr-text);
209
+ font-family: var(--pmr-font-mono);
210
+ font-size: 11px;
211
+ max-width: 180px;
212
+ padding: 1px 4px;
213
+ width: 100%;
214
+ }
215
+ .pmr-textarea {
216
+ min-height: 34px;
217
+ resize: vertical;
218
+ }
219
+ .pmr-input:focus,
220
+ .pmr-select:focus,
221
+ .pmr-textarea:focus {
222
+ border-color: var(--pmr-accent);
223
+ outline: none;
224
+ }
225
+ .pmr-icon-button {
226
+ background: none;
227
+ border: 1px solid var(--pmr-border);
228
+ border-radius: 4px;
229
+ color: var(--pmr-text-muted);
230
+ cursor: pointer;
231
+ font: inherit;
232
+ font-size: 10px;
233
+ padding: 1px 6px;
234
+ }
235
+ .pmr-icon-button:hover {
236
+ border-color: var(--pmr-accent);
237
+ color: var(--pmr-text);
238
+ }
239
+ .pmr-icon-button[data-active="true"] {
240
+ border-color: var(--pmr-accent);
241
+ color: var(--pmr-accent);
242
+ }
243
+ .pmr-preview {
244
+ font-family: var(--pmr-font-mono);
245
+ font-size: 10px;
246
+ }
247
+ .pmr-preview--error {
248
+ color: var(--pmr-status-error);
249
+ }
250
+ .pmr-preview--ok {
251
+ color: var(--pmr-text-muted);
252
+ }
253
+
254
+ .pmr-issues {
255
+ border: 1px solid var(--pmr-status-error);
256
+ border-radius: 6px;
257
+ margin-top: 10px;
258
+ padding: 6px 10px;
259
+ }
260
+ .pmr-issues .pmr-section-title {
261
+ color: var(--pmr-status-error);
262
+ margin-top: 0;
263
+ }
264
+
265
+ .pmr-empty {
266
+ color: var(--pmr-text-muted);
267
+ font-style: italic;
268
+ margin: auto;
269
+ padding: 24px;
270
+ text-align: center;
271
+ }
272
+
273
+ .pmr-toolbar {
274
+ display: flex;
275
+ gap: 4px;
276
+ margin-left: auto;
277
+ }
278
+ `;
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@paramour-js/devtools-panel",
3
+ "version": "0.6.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "default": "./dist/index.js"
9
+ }
10
+ },
11
+ "engines": {
12
+ "node": ">=22.13.0"
13
+ },
14
+ "peerDependencies": {
15
+ "@paramour-js/next": ">=0.6.0",
16
+ "@tanstack/react-devtools": ">=0.10.0",
17
+ "paramour": ">=0.6.0",
18
+ "react": ">=18.2.0"
19
+ },
20
+ "peerDependenciesMeta": {
21
+ "@paramour-js/next": {
22
+ "optional": true
23
+ }
24
+ },
25
+ "devDependencies": {
26
+ "@tanstack/react-devtools": "^0.10.8",
27
+ "@testing-library/dom": "^10.4.0",
28
+ "@testing-library/react": "^16.1.0",
29
+ "@types/node": "^24.0.0",
30
+ "@types/react": "^19.2.0",
31
+ "@types/react-dom": "^19.2.0",
32
+ "happy-dom": "^15.11.0",
33
+ "react": "^19.2.0",
34
+ "react-dom": "^19.2.0",
35
+ "typescript": "^6.0.3",
36
+ "zod": "^4.4.3",
37
+ "@paramour-js/next": "0.6.0",
38
+ "paramour": "0.6.0"
39
+ },
40
+ "description": "Paramour devtools: a TanStack Devtools panel showing live route observations — wire vs parsed values, codec shapes, default/catch attribution, decode issues, and editable search params.",
41
+ "author": "Jason Paff <jasonpaff@gmail.com>",
42
+ "keywords": [
43
+ "nextjs",
44
+ "devtools",
45
+ "tanstack-devtools",
46
+ "routing",
47
+ "typescript",
48
+ "type-safe"
49
+ ],
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/JasonPaff/paramour.git",
54
+ "directory": "packages/devtools"
55
+ },
56
+ "homepage": "https://paramour.dev/docs/reference/devtools",
57
+ "bugs": {
58
+ "url": "https://github.com/JasonPaff/paramour/issues"
59
+ },
60
+ "files": [
61
+ "dist"
62
+ ],
63
+ "publishConfig": {
64
+ "access": "public",
65
+ "provenance": true
66
+ },
67
+ "scripts": {
68
+ "build": "tsc -p tsconfig.build.json",
69
+ "check:publish": "publint --strict && attw --pack . --profile esm-only",
70
+ "typecheck": "tsc --noEmit"
71
+ }
72
+ }