Skip to content

Commit 63bfe17

Browse files
committed
v2.1.3 - Json reader defer and depth upgrade
1 parent c63acd3 commit 63bfe17

9 files changed

Lines changed: 75 additions & 19 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<center>
2-
<img src="./assets/remix-dev-tools.png" align="center" style="width:160px; height:160px;" />
2+
<img src="./assets/remix-dev-tools.png" align="middle" width="160" height="160" alt="Remix Development Tools" />
33
</center>
44

55
# Remix Development Tools
@@ -22,6 +22,9 @@ Remix Development Tools is an open-source package designed to enhance your devel
2222

2323
## What's new?
2424

25+
## v2.1.3
26+
- Deferred data support! You can see your deferred data in the active page tab now being loaded and swapped in realtime
27+
- Settings option to change the default expansion level of json viewer (Default: 0)
2528
### v2.1.0
2629
Detached mode support!
2730

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "remix-development-tools",
33
"description": "Remix development tools.",
44
"author": "Alem Tuzlak",
5-
"version": "2.1.2",
5+
"version": "2.1.3",
66
"license": "MIT",
77
"keywords": [
88
"remix",
Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,49 @@
11
import JsonView from "@uiw/react-json-view";
22
import { darkTheme } from "@uiw/react-json-view/dark";
3+
import { useMemo, useState } from "react";
4+
import { useSettingsContext } from "../context/useRDTContext";
35

46
interface JsonRendererProps {
57
data: string | Record<string, unknown>;
68
}
79

10+
const isPromise = (value: any): value is Promise<any> => {
11+
return value && typeof value.then === "function";
12+
};
13+
814
const JsonRenderer = ({ data }: JsonRendererProps) => {
9-
if (typeof data === "string") {
10-
return <div className="rdt-text-green-600">{data}</div>;
15+
const { settings } = useSettingsContext();
16+
const originalData = useMemo(
17+
() =>
18+
typeof data === "string"
19+
? data
20+
: Object.entries(data)
21+
.map(([key, value]) => {
22+
if (isPromise(value)) {
23+
value.then((res) => {
24+
setJson((json: any) => ({
25+
...json,
26+
[key]: res,
27+
}));
28+
});
29+
return { [key]: "Loading deferred data..." };
30+
}
31+
return { [key]: value };
32+
})
33+
.reduce((acc, curr) => {
34+
return { ...acc, ...curr };
35+
}, {}),
36+
[data]
37+
);
38+
const [json, setJson] = useState(originalData);
39+
40+
if (typeof json === "string") {
41+
return <div className="rdt-text-green-600">{json}</div>;
1142
}
12-
return <JsonView collapsed={0} style={{ ...(darkTheme as any) }} value={data} />;
43+
44+
return (
45+
<JsonView highlightUpdates collapsed={settings.expansionLevel} style={{ ...(darkTheme as any) }} value={json} />
46+
);
1347
};
1448

1549
export { JsonRenderer };

src/RemixDevTools/context/RDTContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const RDTContextProvider = ({ children }: ContextProps) => {
9090
const { settings, detachedWindow, detachedWindowOwner, ...rest } = state;
9191
// Store user settings for dev tools into local storage
9292
setStorageItem(REMIX_DEV_TOOLS_SETTINGS, JSON.stringify(settings));
93-
// Store general state into session storage
93+
// Store general state into local storage
9494
setStorageItem(REMIX_DEV_TOOLS_STATE, JSON.stringify(rest));
9595
}, [state]);
9696

src/RemixDevTools/context/rdtReducer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export type RemixDevToolsState = {
3636
defaultOpen: boolean;
3737
hideUntilHover: boolean;
3838
position: TriggerPosition;
39+
expansionLevel: number;
3940
hoveredRoute: string;
4041
isHoveringRoute: boolean;
4142
};
@@ -59,6 +60,7 @@ export const initialState: RemixDevToolsState = {
5960
defaultOpen: false,
6061
hideUntilHover: false,
6162
position: "bottom-right",
63+
expansionLevel: 0,
6264
hoveredRoute: "",
6365
isHoveringRoute: false,
6466
},

src/RemixDevTools/hooks/detached/useListenToRouteChange.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,17 @@ export const useListenToRouteChange = () => {
2020
const ref = useRef(locationRoute);
2121
const route = getRouteFromLocalStorage();
2222

23+
// Used by the owner window only
2324
useEffect(() => {
25+
// If the route changes and this is the original window store the event into local storage
2426
if (route !== locationRoute && detachedWindowOwner) {
2527
setRouteInLocalStorage(locationRoute);
2628
}
2729
}, [locationRoute, detachedWindowOwner, route]);
2830

31+
// Used to sync the route between the routes
2932
useAttachListener("storage", "window", (e: any) => {
33+
// We only care about the key that changes the route
3034
if (e.key !== LOCAL_STORAGE_ROUTE_KEY) {
3135
return;
3236
}

src/RemixDevTools/tabs/SettingsTab.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const SettingsTab = () => {
1111
const { settings, setSettings } = useSettingsContext();
1212
const [minHeight, setMinHeight] = useState(settings.minHeight.toString());
1313
const [maxHeight, setMaxHeight] = useState(settings.maxHeight.toString());
14+
const [expansionLevel, setExpansionLevel] = useState(settings.expansionLevel.toString());
1415
return (
1516
<Stack className="rdt-mb-4">
1617
<h1>
@@ -28,9 +29,7 @@ export const SettingsTab = () => {
2829
<Checkbox
2930
id="hideUntilHover"
3031
hint="The dev tools trigger will be hidden on the page until you hover over it."
31-
onChange={() =>
32-
setSettings({ hideUntilHover: !settings.hideUntilHover })
33-
}
32+
onChange={() => setSettings({ hideUntilHover: !settings.hideUntilHover })}
3433
value={settings.hideUntilHover}
3534
>
3635
Hide the trigger until hovered
@@ -46,12 +45,7 @@ export const SettingsTab = () => {
4645
onChange={(e) => setMinHeight(e.target.value ?? "")}
4746
onBlur={(e) => {
4847
const value = parseInt(e.target.value);
49-
if (
50-
value &&
51-
!isNaN(value) &&
52-
value < settings.maxHeight &&
53-
value > 100
54-
) {
48+
if (value && !isNaN(value) && value < settings.maxHeight && value > 100) {
5549
setSettings({ minHeight: value });
5650
}
5751
}}
@@ -70,6 +64,20 @@ export const SettingsTab = () => {
7064
}
7165
}}
7266
/>
67+
<Input
68+
name="expansionLevel"
69+
id="expansionLevel"
70+
label="Depth of expansion for JSON objects"
71+
hint="This allows you to change the depth of expanded properties of json objects."
72+
value={expansionLevel}
73+
onChange={(e) => setExpansionLevel(e.target.value ?? "")}
74+
onBlur={(e) => {
75+
const value = parseInt(e.target.value);
76+
if (value && !isNaN(value) && value >= 0) {
77+
setSettings({ expansionLevel: value });
78+
}
79+
}}
80+
/>
7381
<SelectWithOptions
7482
label="Trigger position"
7583
onSelect={(value) => setSettings({ position: value })}

src/remix-app-for-testing/app/routes/_index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ActionArgs } from "@remix-run/node";
2-
import { json, redirect, type LoaderArgs } from "@remix-run/node";
2+
import { json, redirect, type LoaderArgs, defer } from "@remix-run/node";
33
import type { V2_MetaFunction } from "@remix-run/node";
44
import { Link, useFetcher, useLoaderData, useSubmit } from "@remix-run/react";
55

@@ -11,7 +11,12 @@ export const meta: V2_MetaFunction = () => {
1111
};
1212

1313
export const loader = async ({ request }: LoaderArgs) => {
14-
return json({ message: "Hello World!" });
14+
const test = new Promise((resolve) => {
15+
setTimeout(() => {
16+
resolve("test");
17+
}, 1000);
18+
})
19+
return defer({ message: "Hello World!", test });
1520
};
1621

1722
export const action = async ({ request }: ActionArgs) => {

0 commit comments

Comments
 (0)