Skip to content

Commit 432b8cd

Browse files
committed
Add FormDataViewer
1 parent f265c34 commit 432b8cd

File tree

11 files changed

+434
-210
lines changed

11 files changed

+434
-210
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[data-start-form-data-viewer] svg {
2+
width: 1rem;
3+
height: 1rem;
4+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { createResource, For, Show, Suspense, type JSX } from 'solid-js';
2+
3+
import { SerovalValue } from './SerovalValue.tsx';
4+
import { PropertySeparator } from '../ui/Properties.tsx';
5+
import { Section } from '../ui/Section';
6+
import Button from '../ui/Button';
7+
import { Badge } from '../ui/Badge.tsx';
8+
9+
10+
import './FormDataViewer.css';
11+
12+
function DocumentIcon(
13+
props: JSX.IntrinsicElements["svg"] & { title: string },
14+
): JSX.Element {
15+
return (
16+
<svg
17+
xmlns="http://www.w3.org/2000/svg"
18+
fill="none"
19+
viewBox="0 0 24 24"
20+
stroke="currentColor"
21+
{...props}
22+
>
23+
<title>{props.title}</title>
24+
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
25+
</svg>
26+
);
27+
}
28+
29+
interface FormDataViewerInnerProps {
30+
source: FormData;
31+
}
32+
33+
function FormDataViewerInner(props: FormDataViewerInnerProps): JSX.Element {
34+
function openFileInNewTab(file: File) {
35+
const fileURL = URL.createObjectURL(file);
36+
const link = document.createElement("a");
37+
link.href = fileURL;
38+
link.target = "_blank"; // Open in a new tab
39+
link.style.display = "none"; // Hide the link
40+
document.body.appendChild(link);
41+
link.click();
42+
document.body.removeChild(link);
43+
}
44+
45+
return (
46+
<Section title="FormData" options={{ size: 'sm' }}>
47+
<div data-start-form-data-viewer data-start-seroval-properties>
48+
<For each={Array.from(props.source.entries())}>
49+
{([key, value]) => (
50+
<div data-start-seroval-property>
51+
<SerovalValue value={`"${key}"`} />
52+
<PropertySeparator />
53+
{typeof value === 'string'
54+
? <SerovalValue value={JSON.stringify(value)} />
55+
: (
56+
<Button onClick={() => openFileInNewTab(value)}>
57+
<Badge type="info">
58+
<DocumentIcon title={value.name} />
59+
{value.name}
60+
</Badge>
61+
</Button>
62+
)}
63+
</div>
64+
)}
65+
</For>
66+
</div>
67+
</Section>
68+
);
69+
}
70+
71+
export interface FormDataViewerProps {
72+
source: FormData | Promise<FormData>;
73+
}
74+
75+
export function FormDataViewer(props: FormDataViewerProps) {
76+
const [data] = createResource(() => props.source);
77+
78+
return (
79+
<Suspense>
80+
<Show when={data()}>
81+
{(current) => <FormDataViewerInner source={current()} />}
82+
</Show>
83+
</Suspense>
84+
);
85+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
3+
[data-start-seroval-value] {
4+
display: flex;
5+
gap: 0.25rem;
6+
align-items: center;
7+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Text } from "../ui/Text.tsx";
2+
import './SerovalValue.css';
3+
4+
interface SerovalValueProps {
5+
value: string | number | boolean | undefined | null;
6+
}
7+
8+
export function SerovalValue(props: SerovalValueProps) {
9+
return (
10+
<Text data-start-seroval-value options={{ size: 'xs', weight: 'semibold', wrap: 'nowrap' }}>
11+
{`${props.value}`}
12+
</Text>
13+
);
14+
}

packages/start/src/shared/server-function-inspector/SerovalViewer.css

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
[data-start-seroval-viewer] {
22
display: grid;
33
grid-template-columns: 1fr 2fr;
4-
border: 1px oklch(70.7% 0.165 254.624) solid;
5-
overflow: auto;
6-
width: 100%;
7-
max-height: 50vh;
8-
}
9-
10-
[data-start-seroval-value] {
11-
display: flex;
12-
gap: 0.25rem;
13-
align-items: center;
144
}
155

166
[data-start-seroval-promise] {
@@ -21,9 +11,11 @@
2111

2212
[data-start-seroval-renderer] {
2313
display: flex;
14+
border-top: 1px oklch(70.7% 0.165 254.624) solid;
15+
border-bottom: 1px oklch(70.7% 0.165 254.624) solid;
2416
}
2517

26-
[data-start-seroval-renderer] > * + * {
18+
[data-start-seroval-renderer] > * {
2719
border-left: 1px oklch(70.7% 0.165 254.624) solid;
2820
}
2921

0 commit comments

Comments
 (0)