@tanstack/router-devtools 1.111.11 → 1.112.4

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.
Files changed (48) hide show
  1. package/dist/cjs/AgeTicker.cjs +58 -0
  2. package/dist/cjs/AgeTicker.cjs.map +1 -0
  3. package/dist/cjs/AgeTicker.d.cts +5 -0
  4. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.cjs +421 -0
  5. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.cjs.map +1 -0
  6. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.d.cts +3 -0
  7. package/dist/cjs/TanStackRouterDevtools.cjs +177 -0
  8. package/dist/cjs/TanStackRouterDevtools.cjs.map +1 -0
  9. package/dist/cjs/{devtools.d.cts → TanStackRouterDevtools.d.cts} +0 -31
  10. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs +21 -0
  11. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs.map +1 -0
  12. package/dist/cjs/TanStackRouterDevtoolsPanel.d.cts +33 -0
  13. package/dist/cjs/index.cjs +4 -3
  14. package/dist/cjs/index.cjs.map +1 -1
  15. package/dist/cjs/index.d.cts +2 -1
  16. package/dist/cjs/useStyles.cjs +570 -0
  17. package/dist/cjs/useStyles.cjs.map +1 -0
  18. package/dist/cjs/useStyles.d.cts +52 -0
  19. package/dist/esm/AgeTicker.d.ts +5 -0
  20. package/dist/esm/AgeTicker.js +58 -0
  21. package/dist/esm/AgeTicker.js.map +1 -0
  22. package/dist/esm/BaseTanStackRouterDevtoolsPanel.d.ts +3 -0
  23. package/dist/esm/BaseTanStackRouterDevtoolsPanel.js +421 -0
  24. package/dist/esm/BaseTanStackRouterDevtoolsPanel.js.map +1 -0
  25. package/dist/esm/{devtools.d.ts → TanStackRouterDevtools.d.ts} +0 -31
  26. package/dist/esm/TanStackRouterDevtools.js +177 -0
  27. package/dist/esm/TanStackRouterDevtools.js.map +1 -0
  28. package/dist/esm/TanStackRouterDevtoolsPanel.d.ts +33 -0
  29. package/dist/esm/TanStackRouterDevtoolsPanel.js +21 -0
  30. package/dist/esm/TanStackRouterDevtoolsPanel.js.map +1 -0
  31. package/dist/esm/index.d.ts +2 -1
  32. package/dist/esm/index.js +2 -1
  33. package/dist/esm/index.js.map +1 -1
  34. package/dist/esm/useStyles.d.ts +52 -0
  35. package/dist/esm/useStyles.js +553 -0
  36. package/dist/esm/useStyles.js.map +1 -0
  37. package/package.json +2 -2
  38. package/src/AgeTicker.tsx +73 -0
  39. package/src/BaseTanStackRouterDevtoolsPanel.tsx +488 -0
  40. package/src/TanStackRouterDevtools.tsx +250 -0
  41. package/src/TanStackRouterDevtoolsPanel.tsx +54 -0
  42. package/src/index.tsx +2 -1
  43. package/src/useStyles.tsx +589 -0
  44. package/dist/cjs/devtools.cjs +0 -1212
  45. package/dist/cjs/devtools.cjs.map +0 -1
  46. package/dist/esm/devtools.js +0 -1195
  47. package/dist/esm/devtools.js.map +0 -1
  48. package/src/devtools.tsx +0 -1443
@@ -0,0 +1,553 @@
1
+ import React__default from "react";
2
+ import * as goober from "goober";
3
+ import { tokens } from "./tokens.js";
4
+ import { ShadowDomTargetContext } from "./context.js";
5
+ const stylesFactory = (shadowDOMTarget) => {
6
+ const { colors, font, size, alpha, border } = tokens;
7
+ const { fontFamily, lineHeight, size: fontSize } = font;
8
+ const css = shadowDOMTarget ? goober.css.bind({ target: shadowDOMTarget }) : goober.css;
9
+ return {
10
+ devtoolsPanelContainer: css`
11
+ direction: ltr;
12
+ position: fixed;
13
+ bottom: 0;
14
+ right: 0;
15
+ z-index: 99999;
16
+ width: 100%;
17
+ max-height: 90%;
18
+ border-top: 1px solid ${colors.gray[700]};
19
+ transform-origin: top;
20
+ `,
21
+ devtoolsPanelContainerVisibility: (isOpen) => {
22
+ return css`
23
+ visibility: ${isOpen ? "visible" : "hidden"};
24
+ `;
25
+ },
26
+ devtoolsPanelContainerResizing: (isResizing) => {
27
+ if (isResizing) {
28
+ return css`
29
+ transition: none;
30
+ `;
31
+ }
32
+ return css`
33
+ transition: all 0.4s ease;
34
+ `;
35
+ },
36
+ devtoolsPanelContainerAnimation: (isOpen, height) => {
37
+ if (isOpen) {
38
+ return css`
39
+ pointer-events: auto;
40
+ transform: translateY(0);
41
+ `;
42
+ }
43
+ return css`
44
+ pointer-events: none;
45
+ transform: translateY(${height}px);
46
+ `;
47
+ },
48
+ logo: css`
49
+ cursor: pointer;
50
+ display: flex;
51
+ flex-direction: column;
52
+ background-color: transparent;
53
+ border: none;
54
+ font-family: ${fontFamily.sans};
55
+ gap: ${tokens.size[0.5]};
56
+ padding: 0px;
57
+ &:hover {
58
+ opacity: 0.7;
59
+ }
60
+ &:focus-visible {
61
+ outline-offset: 4px;
62
+ border-radius: ${border.radius.xs};
63
+ outline: 2px solid ${colors.blue[800]};
64
+ }
65
+ `,
66
+ tanstackLogo: css`
67
+ font-size: ${font.size.md};
68
+ font-weight: ${font.weight.bold};
69
+ line-height: ${font.lineHeight.xs};
70
+ white-space: nowrap;
71
+ color: ${colors.gray[300]};
72
+ `,
73
+ routerLogo: css`
74
+ font-weight: ${font.weight.semibold};
75
+ font-size: ${font.size.xs};
76
+ background: linear-gradient(to right, #84cc16, #10b981);
77
+ background-clip: text;
78
+ -webkit-background-clip: text;
79
+ line-height: 1;
80
+ -webkit-text-fill-color: transparent;
81
+ white-space: nowrap;
82
+ `,
83
+ devtoolsPanel: css`
84
+ display: flex;
85
+ font-size: ${fontSize.sm};
86
+ font-family: ${fontFamily.sans};
87
+ background-color: ${colors.darkGray[700]};
88
+ color: ${colors.gray[300]};
89
+
90
+ @media (max-width: 700px) {
91
+ flex-direction: column;
92
+ }
93
+ @media (max-width: 600px) {
94
+ font-size: ${fontSize.xs};
95
+ }
96
+ `,
97
+ dragHandle: css`
98
+ position: absolute;
99
+ left: 0;
100
+ top: 0;
101
+ width: 100%;
102
+ height: 4px;
103
+ cursor: row-resize;
104
+ z-index: 100000;
105
+ &:hover {
106
+ background-color: ${colors.purple[400]}${alpha[90]};
107
+ }
108
+ `,
109
+ firstContainer: css`
110
+ flex: 1 1 500px;
111
+ min-height: 40%;
112
+ max-height: 100%;
113
+ overflow: auto;
114
+ border-right: 1px solid ${colors.gray[700]};
115
+ display: flex;
116
+ flex-direction: column;
117
+ `,
118
+ routerExplorerContainer: css`
119
+ overflow-y: auto;
120
+ flex: 1;
121
+ `,
122
+ routerExplorer: css`
123
+ padding: ${tokens.size[2]};
124
+ `,
125
+ row: css`
126
+ display: flex;
127
+ align-items: center;
128
+ padding: ${tokens.size[2]} ${tokens.size[2.5]};
129
+ gap: ${tokens.size[2.5]};
130
+ border-bottom: ${colors.darkGray[500]} 1px solid;
131
+ align-items: center;
132
+ `,
133
+ detailsHeader: css`
134
+ font-family: ui-sans-serif, Inter, system-ui, sans-serif, sans-serif;
135
+ position: sticky;
136
+ top: 0;
137
+ z-index: 2;
138
+ background-color: ${colors.darkGray[600]};
139
+ padding: 0px ${tokens.size[2]};
140
+ font-weight: ${font.weight.medium};
141
+ font-size: ${font.size.xs};
142
+ min-height: ${tokens.size[8]};
143
+ line-height: ${font.lineHeight.xs};
144
+ text-align: left;
145
+ display: flex;
146
+ align-items: center;
147
+ `,
148
+ maskedBadge: css`
149
+ background: ${colors.yellow[900]}${alpha[70]};
150
+ color: ${colors.yellow[300]};
151
+ display: inline-block;
152
+ padding: ${tokens.size[0]} ${tokens.size[2.5]};
153
+ border-radius: ${border.radius.full};
154
+ font-size: ${font.size.xs};
155
+ font-weight: ${font.weight.normal};
156
+ border: 1px solid ${colors.yellow[300]};
157
+ `,
158
+ maskedLocation: css`
159
+ color: ${colors.yellow[300]};
160
+ `,
161
+ detailsContent: css`
162
+ padding: ${tokens.size[1.5]} ${tokens.size[2]};
163
+ display: flex;
164
+ align-items: center;
165
+ justify-content: space-between;
166
+ font-size: ${font.size.xs};
167
+ `,
168
+ routeMatchesToggle: css`
169
+ display: flex;
170
+ align-items: center;
171
+ border: 1px solid ${colors.gray[500]};
172
+ border-radius: ${border.radius.sm};
173
+ overflow: hidden;
174
+ `,
175
+ routeMatchesToggleBtn: (active, showBorder) => {
176
+ const base = css`
177
+ appearance: none;
178
+ border: none;
179
+ font-size: 12px;
180
+ padding: 4px 8px;
181
+ background: transparent;
182
+ cursor: pointer;
183
+ font-family: ${fontFamily.sans};
184
+ font-weight: ${font.weight.medium};
185
+ `;
186
+ const classes = [base];
187
+ if (active) {
188
+ const activeStyles = css`
189
+ background: ${colors.darkGray[400]};
190
+ color: ${colors.gray[300]};
191
+ `;
192
+ classes.push(activeStyles);
193
+ } else {
194
+ const inactiveStyles = css`
195
+ color: ${colors.gray[500]};
196
+ background: ${colors.darkGray[800]}${alpha[20]};
197
+ `;
198
+ classes.push(inactiveStyles);
199
+ }
200
+ if (showBorder) {
201
+ classes.push(css`
202
+ border-right: 1px solid ${tokens.colors.gray[500]};
203
+ `);
204
+ }
205
+ return classes;
206
+ },
207
+ detailsHeaderInfo: css`
208
+ flex: 1;
209
+ justify-content: flex-end;
210
+ display: flex;
211
+ align-items: center;
212
+ font-weight: ${font.weight.normal};
213
+ color: ${colors.gray[400]};
214
+ `,
215
+ matchRow: (active) => {
216
+ const base = css`
217
+ display: flex;
218
+ border-bottom: 1px solid ${colors.darkGray[400]};
219
+ cursor: pointer;
220
+ align-items: center;
221
+ padding: ${size[1]} ${size[2]};
222
+ gap: ${size[2]};
223
+ font-size: ${fontSize.xs};
224
+ color: ${colors.gray[300]};
225
+ `;
226
+ const classes = [base];
227
+ if (active) {
228
+ const activeStyles = css`
229
+ background: ${colors.darkGray[500]};
230
+ `;
231
+ classes.push(activeStyles);
232
+ }
233
+ return classes;
234
+ },
235
+ matchIndicator: (color) => {
236
+ const base = css`
237
+ flex: 0 0 auto;
238
+ width: ${size[3]};
239
+ height: ${size[3]};
240
+ background: ${colors[color][900]};
241
+ border: 1px solid ${colors[color][500]};
242
+ border-radius: ${border.radius.full};
243
+ transition: all 0.25s ease-out;
244
+ box-sizing: border-box;
245
+ `;
246
+ const classes = [base];
247
+ if (color === "gray") {
248
+ const grayStyles = css`
249
+ background: ${colors.gray[700]};
250
+ border-color: ${colors.gray[400]};
251
+ `;
252
+ classes.push(grayStyles);
253
+ }
254
+ return classes;
255
+ },
256
+ matchID: css`
257
+ flex: 1;
258
+ line-height: ${lineHeight["xs"]};
259
+ `,
260
+ ageTicker: (showWarning) => {
261
+ const base = css`
262
+ display: flex;
263
+ gap: ${size[1]};
264
+ font-size: ${fontSize.xs};
265
+ color: ${colors.gray[400]};
266
+ font-variant-numeric: tabular-nums;
267
+ line-height: ${lineHeight["xs"]};
268
+ `;
269
+ const classes = [base];
270
+ if (showWarning) {
271
+ const warningStyles = css`
272
+ color: ${colors.yellow[400]};
273
+ `;
274
+ classes.push(warningStyles);
275
+ }
276
+ return classes;
277
+ },
278
+ secondContainer: css`
279
+ flex: 1 1 500px;
280
+ min-height: 40%;
281
+ max-height: 100%;
282
+ overflow: auto;
283
+ border-right: 1px solid ${colors.gray[700]};
284
+ display: flex;
285
+ flex-direction: column;
286
+ `,
287
+ thirdContainer: css`
288
+ flex: 1 1 500px;
289
+ overflow: auto;
290
+ display: flex;
291
+ flex-direction: column;
292
+ height: 100%;
293
+ border-right: 1px solid ${colors.gray[700]};
294
+
295
+ @media (max-width: 700px) {
296
+ border-top: 2px solid ${colors.gray[700]};
297
+ }
298
+ `,
299
+ fourthContainer: css`
300
+ flex: 1 1 500px;
301
+ min-height: 40%;
302
+ max-height: 100%;
303
+ overflow: auto;
304
+ display: flex;
305
+ flex-direction: column;
306
+ `,
307
+ routesContainer: css`
308
+ overflow-x: auto;
309
+ overflow-y: visible;
310
+ `,
311
+ routesRowContainer: (active, isMatch) => {
312
+ const base = css`
313
+ display: flex;
314
+ border-bottom: 1px solid ${colors.darkGray[400]};
315
+ align-items: center;
316
+ padding: ${size[1]} ${size[2]};
317
+ gap: ${size[2]};
318
+ font-size: ${fontSize.xs};
319
+ color: ${colors.gray[300]};
320
+ cursor: ${isMatch ? "pointer" : "default"};
321
+ line-height: ${lineHeight["xs"]};
322
+ `;
323
+ const classes = [base];
324
+ if (active) {
325
+ const activeStyles = css`
326
+ background: ${colors.darkGray[500]};
327
+ `;
328
+ classes.push(activeStyles);
329
+ }
330
+ return classes;
331
+ },
332
+ routesRow: (isMatch) => {
333
+ const base = css`
334
+ flex: 1 0 auto;
335
+ display: flex;
336
+ justify-content: space-between;
337
+ align-items: center;
338
+ font-size: ${fontSize.xs};
339
+ line-height: ${lineHeight["xs"]};
340
+ `;
341
+ const classes = [base];
342
+ if (!isMatch) {
343
+ const matchStyles = css`
344
+ color: ${colors.gray[400]};
345
+ `;
346
+ classes.push(matchStyles);
347
+ }
348
+ return classes;
349
+ },
350
+ routeParamInfo: css`
351
+ color: ${colors.gray[400]};
352
+ font-size: ${fontSize.xs};
353
+ line-height: ${lineHeight["xs"]};
354
+ `,
355
+ nestedRouteRow: (isRoot) => {
356
+ const base = css`
357
+ margin-left: ${isRoot ? 0 : size[3.5]};
358
+ border-left: ${isRoot ? "" : `solid 1px ${colors.gray[700]}`};
359
+ `;
360
+ return base;
361
+ },
362
+ code: css`
363
+ font-size: ${fontSize.xs};
364
+ line-height: ${lineHeight["xs"]};
365
+ `,
366
+ matchesContainer: css`
367
+ flex: 1 1 auto;
368
+ overflow-y: auto;
369
+ `,
370
+ cachedMatchesContainer: css`
371
+ flex: 1 1 auto;
372
+ overflow-y: auto;
373
+ max-height: 50%;
374
+ `,
375
+ maskedBadgeContainer: css`
376
+ flex: 1;
377
+ justify-content: flex-end;
378
+ display: flex;
379
+ `,
380
+ matchDetails: css`
381
+ display: flex;
382
+ flex-direction: column;
383
+ padding: ${tokens.size[2]};
384
+ font-size: ${tokens.font.size.xs};
385
+ color: ${tokens.colors.gray[300]};
386
+ line-height: ${tokens.font.lineHeight.sm};
387
+ `,
388
+ matchStatus: (status, isFetching) => {
389
+ const colorMap = {
390
+ pending: "yellow",
391
+ success: "green",
392
+ error: "red",
393
+ notFound: "purple",
394
+ redirected: "gray"
395
+ };
396
+ const color = isFetching && status === "success" ? isFetching === "beforeLoad" ? "purple" : "blue" : colorMap[status];
397
+ return css`
398
+ display: flex;
399
+ justify-content: center;
400
+ align-items: center;
401
+ height: 40px;
402
+ border-radius: ${tokens.border.radius.sm};
403
+ font-weight: ${tokens.font.weight.normal};
404
+ background-color: ${tokens.colors[color][900]}${tokens.alpha[90]};
405
+ color: ${tokens.colors[color][300]};
406
+ border: 1px solid ${tokens.colors[color][600]};
407
+ margin-bottom: ${tokens.size[2]};
408
+ transition: all 0.25s ease-out;
409
+ `;
410
+ },
411
+ matchDetailsInfo: css`
412
+ display: flex;
413
+ justify-content: flex-end;
414
+ flex: 1;
415
+ `,
416
+ matchDetailsInfoLabel: css`
417
+ display: flex;
418
+ `,
419
+ mainCloseBtn: css`
420
+ background: ${colors.darkGray[700]};
421
+ padding: ${size[1]} ${size[2]} ${size[1]} ${size[1.5]};
422
+ border-radius: ${border.radius.md};
423
+ position: fixed;
424
+ z-index: 99999;
425
+ display: inline-flex;
426
+ width: fit-content;
427
+ cursor: pointer;
428
+ appearance: none;
429
+ border: 0;
430
+ gap: 8px;
431
+ align-items: center;
432
+ border: 1px solid ${colors.gray[500]};
433
+ font-size: ${font.size.xs};
434
+ cursor: pointer;
435
+ transition: all 0.25s ease-out;
436
+
437
+ &:hover {
438
+ background: ${colors.darkGray[500]};
439
+ }
440
+ `,
441
+ mainCloseBtnPosition: (position) => {
442
+ const base = css`
443
+ ${position === "top-left" ? `top: ${size[2]}; left: ${size[2]};` : ""}
444
+ ${position === "top-right" ? `top: ${size[2]}; right: ${size[2]};` : ""}
445
+ ${position === "bottom-left" ? `bottom: ${size[2]}; left: ${size[2]};` : ""}
446
+ ${position === "bottom-right" ? `bottom: ${size[2]}; right: ${size[2]};` : ""}
447
+ `;
448
+ return base;
449
+ },
450
+ mainCloseBtnAnimation: (isOpen) => {
451
+ if (isOpen) {
452
+ return css`
453
+ opacity: 1;
454
+ pointer-events: auto;
455
+ visibility: visible;
456
+ `;
457
+ }
458
+ return css`
459
+ opacity: 0;
460
+ pointer-events: none;
461
+ visibility: hidden;
462
+ `;
463
+ },
464
+ routerLogoCloseButton: css`
465
+ font-weight: ${font.weight.semibold};
466
+ font-size: ${font.size.xs};
467
+ background: linear-gradient(to right, #98f30c, #00f4a3);
468
+ background-clip: text;
469
+ -webkit-background-clip: text;
470
+ line-height: 1;
471
+ -webkit-text-fill-color: transparent;
472
+ white-space: nowrap;
473
+ `,
474
+ mainCloseBtnDivider: css`
475
+ width: 1px;
476
+ background: ${tokens.colors.gray[600]};
477
+ height: 100%;
478
+ border-radius: 999999px;
479
+ color: transparent;
480
+ `,
481
+ mainCloseBtnIconContainer: css`
482
+ position: relative;
483
+ width: ${size[5]};
484
+ height: ${size[5]};
485
+ background: pink;
486
+ border-radius: 999999px;
487
+ overflow: hidden;
488
+ `,
489
+ mainCloseBtnIconOuter: css`
490
+ width: ${size[5]};
491
+ height: ${size[5]};
492
+ position: absolute;
493
+ top: 50%;
494
+ left: 50%;
495
+ transform: translate(-50%, -50%);
496
+ filter: blur(3px) saturate(1.8) contrast(2);
497
+ `,
498
+ mainCloseBtnIconInner: css`
499
+ width: ${size[4]};
500
+ height: ${size[4]};
501
+ position: absolute;
502
+ top: 50%;
503
+ left: 50%;
504
+ transform: translate(-50%, -50%);
505
+ `,
506
+ panelCloseBtn: css`
507
+ position: absolute;
508
+ cursor: pointer;
509
+ z-index: 100001;
510
+ display: flex;
511
+ align-items: center;
512
+ justify-content: center;
513
+ outline: none;
514
+ background-color: ${colors.darkGray[700]};
515
+ &:hover {
516
+ background-color: ${colors.darkGray[500]};
517
+ }
518
+
519
+ top: 0;
520
+ right: ${size[2]};
521
+ transform: translate(0, -100%);
522
+ border-right: ${colors.darkGray[300]} 1px solid;
523
+ border-left: ${colors.darkGray[300]} 1px solid;
524
+ border-top: ${colors.darkGray[300]} 1px solid;
525
+ border-bottom: none;
526
+ border-radius: ${border.radius.sm} ${border.radius.sm} 0px 0px;
527
+ padding: ${size[1]} ${size[1.5]} ${size[0.5]} ${size[1.5]};
528
+
529
+ &::after {
530
+ content: ' ';
531
+ position: absolute;
532
+ top: 100%;
533
+ left: -${size[2.5]};
534
+ height: ${size[1.5]};
535
+ width: calc(100% + ${size[5]});
536
+ }
537
+ `,
538
+ panelCloseBtnIcon: css`
539
+ color: ${colors.gray[400]};
540
+ width: ${size[2]};
541
+ height: ${size[2]};
542
+ `
543
+ };
544
+ };
545
+ function useStyles() {
546
+ const shadowDomTarget = React__default.useContext(ShadowDomTargetContext);
547
+ const [_styles] = React__default.useState(() => stylesFactory(shadowDomTarget));
548
+ return _styles;
549
+ }
550
+ export {
551
+ useStyles
552
+ };
553
+ //# sourceMappingURL=useStyles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStyles.js","sources":["../../src/useStyles.tsx"],"sourcesContent":["import React from 'react'\n\nimport * as goober from 'goober'\nimport { tokens } from './tokens'\nimport { ShadowDomTargetContext } from './context'\n\nconst stylesFactory = (shadowDOMTarget?: ShadowRoot) => {\n const { colors, font, size, alpha, shadow, border } = tokens\n const { fontFamily, lineHeight, size: fontSize } = font\n const css = shadowDOMTarget\n ? goober.css.bind({ target: shadowDOMTarget })\n : goober.css\n\n return {\n devtoolsPanelContainer: css`\n direction: ltr;\n position: fixed;\n bottom: 0;\n right: 0;\n z-index: 99999;\n width: 100%;\n max-height: 90%;\n border-top: 1px solid ${colors.gray[700]};\n transform-origin: top;\n `,\n devtoolsPanelContainerVisibility: (isOpen: boolean) => {\n return css`\n visibility: ${isOpen ? 'visible' : 'hidden'};\n `\n },\n devtoolsPanelContainerResizing: (isResizing: boolean) => {\n if (isResizing) {\n return css`\n transition: none;\n `\n }\n\n return css`\n transition: all 0.4s ease;\n `\n },\n devtoolsPanelContainerAnimation: (isOpen: boolean, height: number) => {\n if (isOpen) {\n return css`\n pointer-events: auto;\n transform: translateY(0);\n `\n }\n return css`\n pointer-events: none;\n transform: translateY(${height}px);\n `\n },\n logo: css`\n cursor: pointer;\n display: flex;\n flex-direction: column;\n background-color: transparent;\n border: none;\n font-family: ${fontFamily.sans};\n gap: ${tokens.size[0.5]};\n padding: 0px;\n &:hover {\n opacity: 0.7;\n }\n &:focus-visible {\n outline-offset: 4px;\n border-radius: ${border.radius.xs};\n outline: 2px solid ${colors.blue[800]};\n }\n `,\n tanstackLogo: css`\n font-size: ${font.size.md};\n font-weight: ${font.weight.bold};\n line-height: ${font.lineHeight.xs};\n white-space: nowrap;\n color: ${colors.gray[300]};\n `,\n routerLogo: css`\n font-weight: ${font.weight.semibold};\n font-size: ${font.size.xs};\n background: linear-gradient(to right, #84cc16, #10b981);\n background-clip: text;\n -webkit-background-clip: text;\n line-height: 1;\n -webkit-text-fill-color: transparent;\n white-space: nowrap;\n `,\n devtoolsPanel: css`\n display: flex;\n font-size: ${fontSize.sm};\n font-family: ${fontFamily.sans};\n background-color: ${colors.darkGray[700]};\n color: ${colors.gray[300]};\n\n @media (max-width: 700px) {\n flex-direction: column;\n }\n @media (max-width: 600px) {\n font-size: ${fontSize.xs};\n }\n `,\n dragHandle: css`\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 4px;\n cursor: row-resize;\n z-index: 100000;\n &:hover {\n background-color: ${colors.purple[400]}${alpha[90]};\n }\n `,\n firstContainer: css`\n flex: 1 1 500px;\n min-height: 40%;\n max-height: 100%;\n overflow: auto;\n border-right: 1px solid ${colors.gray[700]};\n display: flex;\n flex-direction: column;\n `,\n routerExplorerContainer: css`\n overflow-y: auto;\n flex: 1;\n `,\n routerExplorer: css`\n padding: ${tokens.size[2]};\n `,\n row: css`\n display: flex;\n align-items: center;\n padding: ${tokens.size[2]} ${tokens.size[2.5]};\n gap: ${tokens.size[2.5]};\n border-bottom: ${colors.darkGray[500]} 1px solid;\n align-items: center;\n `,\n detailsHeader: css`\n font-family: ui-sans-serif, Inter, system-ui, sans-serif, sans-serif;\n position: sticky;\n top: 0;\n z-index: 2;\n background-color: ${colors.darkGray[600]};\n padding: 0px ${tokens.size[2]};\n font-weight: ${font.weight.medium};\n font-size: ${font.size.xs};\n min-height: ${tokens.size[8]};\n line-height: ${font.lineHeight.xs};\n text-align: left;\n display: flex;\n align-items: center;\n `,\n maskedBadge: css`\n background: ${colors.yellow[900]}${alpha[70]};\n color: ${colors.yellow[300]};\n display: inline-block;\n padding: ${tokens.size[0]} ${tokens.size[2.5]};\n border-radius: ${border.radius.full};\n font-size: ${font.size.xs};\n font-weight: ${font.weight.normal};\n border: 1px solid ${colors.yellow[300]};\n `,\n maskedLocation: css`\n color: ${colors.yellow[300]};\n `,\n detailsContent: css`\n padding: ${tokens.size[1.5]} ${tokens.size[2]};\n display: flex;\n align-items: center;\n justify-content: space-between;\n font-size: ${font.size.xs};\n `,\n routeMatchesToggle: css`\n display: flex;\n align-items: center;\n border: 1px solid ${colors.gray[500]};\n border-radius: ${border.radius.sm};\n overflow: hidden;\n `,\n routeMatchesToggleBtn: (active: boolean, showBorder: boolean) => {\n const base = css`\n appearance: none;\n border: none;\n font-size: 12px;\n padding: 4px 8px;\n background: transparent;\n cursor: pointer;\n font-family: ${fontFamily.sans};\n font-weight: ${font.weight.medium};\n `\n const classes = [base]\n\n if (active) {\n const activeStyles = css`\n background: ${colors.darkGray[400]};\n color: ${colors.gray[300]};\n `\n classes.push(activeStyles)\n } else {\n const inactiveStyles = css`\n color: ${colors.gray[500]};\n background: ${colors.darkGray[800]}${alpha[20]};\n `\n classes.push(inactiveStyles)\n }\n\n if (showBorder) {\n classes.push(css`\n border-right: 1px solid ${tokens.colors.gray[500]};\n `)\n }\n\n return classes\n },\n detailsHeaderInfo: css`\n flex: 1;\n justify-content: flex-end;\n display: flex;\n align-items: center;\n font-weight: ${font.weight.normal};\n color: ${colors.gray[400]};\n `,\n matchRow: (active: boolean) => {\n const base = css`\n display: flex;\n border-bottom: 1px solid ${colors.darkGray[400]};\n cursor: pointer;\n align-items: center;\n padding: ${size[1]} ${size[2]};\n gap: ${size[2]};\n font-size: ${fontSize.xs};\n color: ${colors.gray[300]};\n `\n const classes = [base]\n\n if (active) {\n const activeStyles = css`\n background: ${colors.darkGray[500]};\n `\n classes.push(activeStyles)\n }\n\n return classes\n },\n matchIndicator: (\n color: 'green' | 'red' | 'yellow' | 'gray' | 'blue' | 'purple',\n ) => {\n const base = css`\n flex: 0 0 auto;\n width: ${size[3]};\n height: ${size[3]};\n background: ${colors[color][900]};\n border: 1px solid ${colors[color][500]};\n border-radius: ${border.radius.full};\n transition: all 0.25s ease-out;\n box-sizing: border-box;\n `\n const classes = [base]\n\n if (color === 'gray') {\n const grayStyles = css`\n background: ${colors.gray[700]};\n border-color: ${colors.gray[400]};\n `\n classes.push(grayStyles)\n }\n\n return classes\n },\n matchID: css`\n flex: 1;\n line-height: ${lineHeight['xs']};\n `,\n ageTicker: (showWarning: boolean) => {\n const base = css`\n display: flex;\n gap: ${size[1]};\n font-size: ${fontSize.xs};\n color: ${colors.gray[400]};\n font-variant-numeric: tabular-nums;\n line-height: ${lineHeight['xs']};\n `\n\n const classes = [base]\n\n if (showWarning) {\n const warningStyles = css`\n color: ${colors.yellow[400]};\n `\n classes.push(warningStyles)\n }\n\n return classes\n },\n secondContainer: css`\n flex: 1 1 500px;\n min-height: 40%;\n max-height: 100%;\n overflow: auto;\n border-right: 1px solid ${colors.gray[700]};\n display: flex;\n flex-direction: column;\n `,\n thirdContainer: css`\n flex: 1 1 500px;\n overflow: auto;\n display: flex;\n flex-direction: column;\n height: 100%;\n border-right: 1px solid ${colors.gray[700]};\n\n @media (max-width: 700px) {\n border-top: 2px solid ${colors.gray[700]};\n }\n `,\n fourthContainer: css`\n flex: 1 1 500px;\n min-height: 40%;\n max-height: 100%;\n overflow: auto;\n display: flex;\n flex-direction: column;\n `,\n routesContainer: css`\n overflow-x: auto;\n overflow-y: visible;\n `,\n routesRowContainer: (active: boolean, isMatch: boolean) => {\n const base = css`\n display: flex;\n border-bottom: 1px solid ${colors.darkGray[400]};\n align-items: center;\n padding: ${size[1]} ${size[2]};\n gap: ${size[2]};\n font-size: ${fontSize.xs};\n color: ${colors.gray[300]};\n cursor: ${isMatch ? 'pointer' : 'default'};\n line-height: ${lineHeight['xs']};\n `\n const classes = [base]\n\n if (active) {\n const activeStyles = css`\n background: ${colors.darkGray[500]};\n `\n classes.push(activeStyles)\n }\n\n return classes\n },\n routesRow: (isMatch: boolean) => {\n const base = css`\n flex: 1 0 auto;\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: ${fontSize.xs};\n line-height: ${lineHeight['xs']};\n `\n\n const classes = [base]\n\n if (!isMatch) {\n const matchStyles = css`\n color: ${colors.gray[400]};\n `\n classes.push(matchStyles)\n }\n\n return classes\n },\n routeParamInfo: css`\n color: ${colors.gray[400]};\n font-size: ${fontSize.xs};\n line-height: ${lineHeight['xs']};\n `,\n nestedRouteRow: (isRoot: boolean) => {\n const base = css`\n margin-left: ${isRoot ? 0 : size[3.5]};\n border-left: ${isRoot ? '' : `solid 1px ${colors.gray[700]}`};\n `\n return base\n },\n code: css`\n font-size: ${fontSize.xs};\n line-height: ${lineHeight['xs']};\n `,\n matchesContainer: css`\n flex: 1 1 auto;\n overflow-y: auto;\n `,\n cachedMatchesContainer: css`\n flex: 1 1 auto;\n overflow-y: auto;\n max-height: 50%;\n `,\n maskedBadgeContainer: css`\n flex: 1;\n justify-content: flex-end;\n display: flex;\n `,\n matchDetails: css`\n display: flex;\n flex-direction: column;\n padding: ${tokens.size[2]};\n font-size: ${tokens.font.size.xs};\n color: ${tokens.colors.gray[300]};\n line-height: ${tokens.font.lineHeight.sm};\n `,\n matchStatus: (\n status: 'pending' | 'success' | 'error' | 'notFound' | 'redirected',\n isFetching: false | 'beforeLoad' | 'loader',\n ) => {\n const colorMap = {\n pending: 'yellow',\n success: 'green',\n error: 'red',\n notFound: 'purple',\n redirected: 'gray',\n } as const\n\n const color =\n isFetching && status === 'success'\n ? isFetching === 'beforeLoad'\n ? 'purple'\n : 'blue'\n : colorMap[status]\n\n return css`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 40px;\n border-radius: ${tokens.border.radius.sm};\n font-weight: ${tokens.font.weight.normal};\n background-color: ${tokens.colors[color][900]}${tokens.alpha[90]};\n color: ${tokens.colors[color][300]};\n border: 1px solid ${tokens.colors[color][600]};\n margin-bottom: ${tokens.size[2]};\n transition: all 0.25s ease-out;\n `\n },\n matchDetailsInfo: css`\n display: flex;\n justify-content: flex-end;\n flex: 1;\n `,\n matchDetailsInfoLabel: css`\n display: flex;\n `,\n mainCloseBtn: css`\n background: ${colors.darkGray[700]};\n padding: ${size[1]} ${size[2]} ${size[1]} ${size[1.5]};\n border-radius: ${border.radius.md};\n position: fixed;\n z-index: 99999;\n display: inline-flex;\n width: fit-content;\n cursor: pointer;\n appearance: none;\n border: 0;\n gap: 8px;\n align-items: center;\n border: 1px solid ${colors.gray[500]};\n font-size: ${font.size.xs};\n cursor: pointer;\n transition: all 0.25s ease-out;\n\n &:hover {\n background: ${colors.darkGray[500]};\n }\n `,\n mainCloseBtnPosition: (\n position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right',\n ) => {\n const base = css`\n ${position === 'top-left' ? `top: ${size[2]}; left: ${size[2]};` : ''}\n ${position === 'top-right' ? `top: ${size[2]}; right: ${size[2]};` : ''}\n ${position === 'bottom-left'\n ? `bottom: ${size[2]}; left: ${size[2]};`\n : ''}\n ${position === 'bottom-right'\n ? `bottom: ${size[2]}; right: ${size[2]};`\n : ''}\n `\n return base\n },\n mainCloseBtnAnimation: (isOpen: boolean) => {\n if (isOpen) {\n return css`\n opacity: 1;\n pointer-events: auto;\n visibility: visible;\n `\n }\n return css`\n opacity: 0;\n pointer-events: none;\n visibility: hidden;\n `\n },\n routerLogoCloseButton: css`\n font-weight: ${font.weight.semibold};\n font-size: ${font.size.xs};\n background: linear-gradient(to right, #98f30c, #00f4a3);\n background-clip: text;\n -webkit-background-clip: text;\n line-height: 1;\n -webkit-text-fill-color: transparent;\n white-space: nowrap;\n `,\n mainCloseBtnDivider: css`\n width: 1px;\n background: ${tokens.colors.gray[600]};\n height: 100%;\n border-radius: 999999px;\n color: transparent;\n `,\n mainCloseBtnIconContainer: css`\n position: relative;\n width: ${size[5]};\n height: ${size[5]};\n background: pink;\n border-radius: 999999px;\n overflow: hidden;\n `,\n mainCloseBtnIconOuter: css`\n width: ${size[5]};\n height: ${size[5]};\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n filter: blur(3px) saturate(1.8) contrast(2);\n `,\n mainCloseBtnIconInner: css`\n width: ${size[4]};\n height: ${size[4]};\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n `,\n panelCloseBtn: css`\n position: absolute;\n cursor: pointer;\n z-index: 100001;\n display: flex;\n align-items: center;\n justify-content: center;\n outline: none;\n background-color: ${colors.darkGray[700]};\n &:hover {\n background-color: ${colors.darkGray[500]};\n }\n\n top: 0;\n right: ${size[2]};\n transform: translate(0, -100%);\n border-right: ${colors.darkGray[300]} 1px solid;\n border-left: ${colors.darkGray[300]} 1px solid;\n border-top: ${colors.darkGray[300]} 1px solid;\n border-bottom: none;\n border-radius: ${border.radius.sm} ${border.radius.sm} 0px 0px;\n padding: ${size[1]} ${size[1.5]} ${size[0.5]} ${size[1.5]};\n\n &::after {\n content: ' ';\n position: absolute;\n top: 100%;\n left: -${size[2.5]};\n height: ${size[1.5]};\n width: calc(100% + ${size[5]});\n }\n `,\n panelCloseBtnIcon: css`\n color: ${colors.gray[400]};\n width: ${size[2]};\n height: ${size[2]};\n `,\n }\n}\n\nexport function useStyles() {\n const shadowDomTarget = React.useContext(ShadowDomTargetContext)\n const [_styles] = React.useState(() => stylesFactory(shadowDomTarget))\n return _styles\n}\n"],"names":["React"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-devtools",
3
- "version": "1.111.11",
3
+ "version": "1.112.4",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -61,7 +61,7 @@
61
61
  "csstype": "^3.0.10",
62
62
  "react": ">=18.0.0 || >=19.0.0",
63
63
  "react-dom": ">=18.0.0 || >=19.0.0",
64
- "@tanstack/react-router": "^1.111.11"
64
+ "@tanstack/react-router": "^1.112.0"
65
65
  },
66
66
  "peerDependenciesMeta": {
67
67
  "csstype": {
@@ -0,0 +1,73 @@
1
+ import { clsx as cx } from 'clsx'
2
+ import React from 'react'
3
+ import { useStyles } from './useStyles'
4
+ import type { AnyRouteMatch, AnyRouter } from '@tanstack/react-router'
5
+
6
+ function formatTime(ms: number) {
7
+ const units = ['s', 'min', 'h', 'd']
8
+ const values = [ms / 1000, ms / 60000, ms / 3600000, ms / 86400000]
9
+
10
+ let chosenUnitIndex = 0
11
+ for (let i = 1; i < values.length; i++) {
12
+ if (values[i]! < 1) break
13
+ chosenUnitIndex = i
14
+ }
15
+
16
+ const formatter = new Intl.NumberFormat(navigator.language, {
17
+ compactDisplay: 'short',
18
+ notation: 'compact',
19
+ maximumFractionDigits: 0,
20
+ })
21
+
22
+ return formatter.format(values[chosenUnitIndex]!) + units[chosenUnitIndex]
23
+ }
24
+
25
+ export function AgeTicker({
26
+ match,
27
+ router,
28
+ }: {
29
+ match?: AnyRouteMatch
30
+ router: AnyRouter
31
+ }) {
32
+ const styles = useStyles()
33
+ const rerender = React.useReducer(
34
+ () => ({}),
35
+ () => ({}),
36
+ )[1]
37
+
38
+ React.useEffect(() => {
39
+ const interval = setInterval(() => {
40
+ rerender()
41
+ }, 1000)
42
+
43
+ return () => {
44
+ clearInterval(interval)
45
+ }
46
+ }, [rerender])
47
+
48
+ if (!match) {
49
+ return null
50
+ }
51
+
52
+ const route = router.looseRoutesById[match.routeId]!
53
+
54
+ if (!route.options.loader) {
55
+ return null
56
+ }
57
+
58
+ const age = Date.now() - match.updatedAt
59
+ const staleTime =
60
+ route.options.staleTime ?? router.options.defaultStaleTime ?? 0
61
+ const gcTime =
62
+ route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1000
63
+
64
+ return (
65
+ <div className={cx(styles.ageTicker(age > staleTime))}>
66
+ <div>{formatTime(age)}</div>
67
+ <div>/</div>
68
+ <div>{formatTime(staleTime)}</div>
69
+ <div>/</div>
70
+ <div>{formatTime(gcTime)}</div>
71
+ </div>
72
+ )
73
+ }