@solidjs/start 2.0.2 → 2.0.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.
- package/CHANGELOG.md +19 -0
- package/dist/server/manifest/prod-ssr-manifest.js +3 -3
- package/dist/shared/dev-toolbar/error-viewer/CodeView.jsx +9 -4
- package/dist/shared/dev-toolbar/error-viewer/create-stack-frame.d.ts +2 -1
- package/dist/shared/dev-toolbar/error-viewer/create-stack-frame.js +29 -19
- package/dist/shared/dev-toolbar/error-viewer/get-source-map.d.ts +2 -2
- package/dist/shared/dev-toolbar/error-viewer/get-source-map.js +3 -2
- package/dist/shared/dev-toolbar/error-viewer/index.jsx +52 -35
- package/dist/shared/dev-toolbar/error-viewer/styles.css +91 -43
- package/dist/shared/dev-toolbar/functions/BlobViewer.css +50 -2
- package/dist/shared/dev-toolbar/functions/BlobViewer.jsx +23 -4
- package/dist/shared/dev-toolbar/functions/FormDataViewer.jsx +9 -6
- package/dist/shared/dev-toolbar/functions/HeadersViewer.css +0 -4
- package/dist/shared/dev-toolbar/functions/HeadersViewer.jsx +9 -7
- package/dist/shared/dev-toolbar/functions/HexViewer.css +36 -17
- package/dist/shared/dev-toolbar/functions/HexViewer.jsx +7 -6
- package/dist/shared/dev-toolbar/functions/SerovalValue.css +21 -0
- package/dist/shared/dev-toolbar/functions/SerovalValue.d.ts +1 -0
- package/dist/shared/dev-toolbar/functions/SerovalValue.jsx +4 -2
- package/dist/shared/dev-toolbar/functions/SerovalViewer.css +98 -36
- package/dist/shared/dev-toolbar/functions/SerovalViewer.jsx +268 -279
- package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.jsx +9 -6
- package/dist/shared/dev-toolbar/functions/index.jsx +96 -69
- package/dist/shared/dev-toolbar/functions/styles.css +143 -10
- package/dist/shared/dev-toolbar/index.css +54 -14
- package/dist/shared/dev-toolbar/index.jsx +8 -1
- package/dist/shared/ui/Badge.css +21 -10
- package/dist/shared/ui/Button.css +7 -6
- package/dist/shared/ui/IconButton.css +16 -10
- package/dist/shared/ui/Placeholder.css +2 -0
- package/dist/shared/ui/Section.css +42 -3
- package/dist/shared/ui/Section.d.ts +3 -1
- package/dist/shared/ui/Section.jsx +14 -6
- package/dist/shared/ui/Select.css +11 -4
- package/dist/shared/ui/Tabs.css +30 -16
- package/package.json +5 -5
- package/dist/shared/ui/Cascade.css +0 -29
- package/dist/shared/ui/Cascade.d.ts +0 -4
- package/dist/shared/ui/Cascade.jsx +0 -4
- package/dist/shared/ui/Dialog.css +0 -25
- package/dist/shared/ui/Dialog.d.ts +0 -5
- package/dist/shared/ui/Dialog.jsx +0 -5
- package/dist/shared/ui/Table.css +0 -22
- package/dist/shared/ui/Table.d.ts +0 -11
- package/dist/shared/ui/Table.jsx +0 -13
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { createResource, For, Show, Suspense } from "solid-js";
|
|
2
2
|
import { Section } from "../../ui/Section.jsx";
|
|
3
|
-
import {
|
|
3
|
+
import { Text } from "../../ui/Text.jsx";
|
|
4
4
|
function URLSearchParamsViewerInner(props) {
|
|
5
5
|
return (<Section title="URLSearchParams" options={{ size: "sm" }}>
|
|
6
|
-
<div data-start-properties>
|
|
6
|
+
<div data-start-properties data-start-kv-table>
|
|
7
7
|
<For each={Array.from(props.source.entries())}>
|
|
8
|
-
{([key, value]) => (<div data-start-property>
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
{([key, value]) => (<div data-start-property data-start-kv-row>
|
|
9
|
+
<Text data-start-kv-key options={{ size: "xs", weight: "semibold", font: "mono", wrap: "nowrap" }}>
|
|
10
|
+
{key}
|
|
11
|
+
</Text>
|
|
12
|
+
<Text data-start-kv-value options={{ size: "xs", font: "mono", wrap: "wrap" }}>
|
|
13
|
+
{JSON.stringify(value)}
|
|
14
|
+
</Text>
|
|
12
15
|
</div>)}
|
|
13
16
|
</For>
|
|
14
17
|
</div>
|
|
@@ -7,12 +7,11 @@ import { Section } from "../../ui/Section.jsx";
|
|
|
7
7
|
import { Select, SelectOption } from "../../ui/Select.jsx";
|
|
8
8
|
import { Tab, TabGroup, TabList, TabPanel } from "../../ui/Tabs.jsx";
|
|
9
9
|
import { Text } from "../../ui/Text.jsx";
|
|
10
|
-
import {
|
|
10
|
+
import { FunctionIcon, TrashIcon } from "../icons.jsx";
|
|
11
11
|
import { BlobViewer } from "./BlobViewer.jsx";
|
|
12
12
|
import { FormDataViewer } from "./FormDataViewer.jsx";
|
|
13
13
|
import { HeadersViewer } from "./HeadersViewer.jsx";
|
|
14
14
|
import { HexViewer } from "./HexViewer.jsx";
|
|
15
|
-
import { PropertySeparator, SerovalValue } from "./SerovalValue.jsx";
|
|
16
15
|
import { SerovalViewer } from "./SerovalViewer.jsx";
|
|
17
16
|
import "./styles.css";
|
|
18
17
|
import { URLSearchParamsViewer } from "./URLSearchParamsViewer.jsx";
|
|
@@ -29,37 +28,43 @@ async function getURLSearchParams(source) {
|
|
|
29
28
|
return new URLSearchParams(text);
|
|
30
29
|
}
|
|
31
30
|
function ContentViewer(props) {
|
|
31
|
+
const body = createMemo(() => {
|
|
32
|
+
const original = props.source.source;
|
|
33
|
+
if (!original.body) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const source = original.clone();
|
|
37
|
+
const startType = source.headers.get(BODY_FORMAT_KEY);
|
|
38
|
+
const contentType = source.headers.get("Content-Type");
|
|
39
|
+
switch (true) {
|
|
40
|
+
case startType === "true":
|
|
41
|
+
case startType === BodyFormat.Seroval:
|
|
42
|
+
return <SerovalViewer stream={source}/>;
|
|
43
|
+
case startType === BodyFormat.String:
|
|
44
|
+
return <HexViewer bytes={source.bytes()}/>;
|
|
45
|
+
case startType === BodyFormat.File:
|
|
46
|
+
return <BlobViewer source={getFile(source)}/>;
|
|
47
|
+
case startType === BodyFormat.FormData:
|
|
48
|
+
case contentType?.startsWith("multipart/form-data"):
|
|
49
|
+
return <FormDataViewer source={source.formData()}/>;
|
|
50
|
+
case startType === BodyFormat.URLSearchParams:
|
|
51
|
+
case contentType?.startsWith("application/x-www-form-urlencoded"):
|
|
52
|
+
return <URLSearchParamsViewer source={getURLSearchParams(source)}/>;
|
|
53
|
+
case startType === BodyFormat.Blob:
|
|
54
|
+
return <BlobViewer source={source.blob()}/>;
|
|
55
|
+
case startType === BodyFormat.ArrayBuffer:
|
|
56
|
+
case startType === BodyFormat.Uint8Array:
|
|
57
|
+
return <HexViewer bytes={source.bytes()}/>;
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
});
|
|
32
61
|
return (<>
|
|
33
|
-
<
|
|
62
|
+
<Show when={body()}>
|
|
63
|
+
<Section title="Body">{body()}</Section>
|
|
64
|
+
</Show>
|
|
65
|
+
<Section collapsible title="Headers">
|
|
34
66
|
<HeadersViewer headers={props.source.source.headers}/>
|
|
35
67
|
</Section>
|
|
36
|
-
<Section title="Body">
|
|
37
|
-
{(() => {
|
|
38
|
-
const source = props.source.source.clone();
|
|
39
|
-
const startType = source.headers.get(BODY_FORMAT_KEY);
|
|
40
|
-
const contentType = source.headers.get("Content-Type");
|
|
41
|
-
switch (true) {
|
|
42
|
-
case startType === "true":
|
|
43
|
-
case startType === BodyFormat.Seroval:
|
|
44
|
-
return <SerovalViewer stream={source}/>;
|
|
45
|
-
case startType === BodyFormat.String:
|
|
46
|
-
return <HexViewer bytes={source.bytes()}/>;
|
|
47
|
-
case startType === BodyFormat.File:
|
|
48
|
-
return <BlobViewer source={getFile(source)}/>;
|
|
49
|
-
case startType === BodyFormat.FormData:
|
|
50
|
-
case contentType?.startsWith("multipart/form-data"):
|
|
51
|
-
return <FormDataViewer source={source.formData()}/>;
|
|
52
|
-
case startType === BodyFormat.URLSearchParams:
|
|
53
|
-
case contentType?.startsWith("application/x-www-form-urlencoded"):
|
|
54
|
-
return <URLSearchParamsViewer source={getURLSearchParams(source)}/>;
|
|
55
|
-
case startType === BodyFormat.Blob:
|
|
56
|
-
return <BlobViewer source={source.blob()}/>;
|
|
57
|
-
case startType === BodyFormat.ArrayBuffer:
|
|
58
|
-
case startType === BodyFormat.Uint8Array:
|
|
59
|
-
return <HexViewer bytes={source.bytes()}/>;
|
|
60
|
-
}
|
|
61
|
-
})()}
|
|
62
|
-
</Section>
|
|
63
68
|
</>);
|
|
64
69
|
}
|
|
65
70
|
function convertRequestToEntries(request) {
|
|
@@ -78,16 +83,21 @@ function convertRequestToEntries(request) {
|
|
|
78
83
|
}
|
|
79
84
|
function RequestViewer(props) {
|
|
80
85
|
return (<TabPanel value="request">
|
|
81
|
-
<Section title="Information">
|
|
82
|
-
<For each={convertRequestToEntries(props.request.source)}>
|
|
83
|
-
{([key, value]) => (<div data-start-property>
|
|
84
|
-
<Text options={{ size: "xs", weight: "semibold", wrap: "nowrap" }}>{key}</Text>
|
|
85
|
-
<PropertySeparator />
|
|
86
|
-
<SerovalValue value={value}/>
|
|
87
|
-
</div>)}
|
|
88
|
-
</For>
|
|
89
|
-
</Section>
|
|
90
86
|
<ContentViewer source={props.request}/>
|
|
87
|
+
<Section collapsible defaultOpen={false} title="Information">
|
|
88
|
+
<div data-start-properties data-start-kv-table>
|
|
89
|
+
<For each={convertRequestToEntries(props.request.source)}>
|
|
90
|
+
{([key, value]) => (<div data-start-property data-start-kv-row>
|
|
91
|
+
<Text data-start-kv-key options={{ size: "xs", weight: "semibold", font: "mono", wrap: "nowrap" }}>
|
|
92
|
+
{key}
|
|
93
|
+
</Text>
|
|
94
|
+
<Text data-start-kv-value options={{ size: "xs", font: "mono", wrap: "wrap" }}>
|
|
95
|
+
{`${value}`}
|
|
96
|
+
</Text>
|
|
97
|
+
</div>)}
|
|
98
|
+
</For>
|
|
99
|
+
</div>
|
|
100
|
+
</Section>
|
|
91
101
|
</TabPanel>);
|
|
92
102
|
}
|
|
93
103
|
function convertResponseToEntries(response) {
|
|
@@ -102,23 +112,33 @@ function convertResponseToEntries(response) {
|
|
|
102
112
|
}
|
|
103
113
|
function ResponseViewer(props) {
|
|
104
114
|
return (<TabPanel value="response">
|
|
105
|
-
<Show when={props.response}>
|
|
115
|
+
<Show when={props.response} fallback={<Placeholder>
|
|
116
|
+
<Text options={{ size: "xs" }}>Waiting for response.</Text>
|
|
117
|
+
</Placeholder>}>
|
|
106
118
|
{instance => (<>
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
<ContentViewer source={instance()}/>
|
|
120
|
+
<Section collapsible defaultOpen={false} title="Information">
|
|
121
|
+
<div data-start-properties data-start-kv-table>
|
|
122
|
+
<For each={convertResponseToEntries(instance().source)}>
|
|
123
|
+
{([key, value]) => (<div data-start-property data-start-kv-row>
|
|
124
|
+
<Text data-start-kv-key options={{ size: "xs", weight: "semibold", font: "mono", wrap: "nowrap" }}>
|
|
125
|
+
{key}
|
|
126
|
+
</Text>
|
|
127
|
+
<Text data-start-kv-value options={{ size: "xs", font: "mono", wrap: "wrap" }}>
|
|
128
|
+
{`${value}`}
|
|
129
|
+
</Text>
|
|
130
|
+
</div>)}
|
|
131
|
+
</For>
|
|
132
|
+
<div data-start-property data-start-kv-row>
|
|
133
|
+
<Text data-start-kv-key options={{ size: "xs", weight: "semibold", font: "mono", wrap: "nowrap" }}>
|
|
134
|
+
Timing
|
|
135
|
+
</Text>
|
|
136
|
+
<Text data-start-kv-value options={{ size: "xs", font: "mono", wrap: "wrap" }}>
|
|
137
|
+
{`${((instance().time - props.request.time) / 1000).toFixed(2)}s`}
|
|
138
|
+
</Text>
|
|
139
|
+
</div>
|
|
119
140
|
</div>
|
|
120
141
|
</Section>
|
|
121
|
-
<ContentViewer source={instance()}/>
|
|
122
142
|
</>)}
|
|
123
143
|
</Show>
|
|
124
144
|
</TabPanel>);
|
|
@@ -144,14 +164,18 @@ function ServerFunctionInstanceViewer(props) {
|
|
|
144
164
|
return (<div data-start-function-instance-viewer>
|
|
145
165
|
<div data-start-function-instance-viewer-nav>
|
|
146
166
|
<div data-start-function-instance-viewer-nav-left>
|
|
147
|
-
<IconButton onClick={props.onReturn}>
|
|
148
|
-
<ArrowLeftIcon title="Go Back"/>
|
|
149
|
-
</IconButton>
|
|
150
167
|
<div>
|
|
151
168
|
<ServerFunctionInstanceDetail id={props.id} value={props.instance}/>
|
|
152
169
|
</div>
|
|
153
170
|
</div>
|
|
154
171
|
<div>
|
|
172
|
+
<Show when={props.instance.response}>
|
|
173
|
+
{response => (<span data-start-function-instance-timing>
|
|
174
|
+
<Text options={{ size: "xs", weight: "semibold", font: "mono", wrap: "nowrap" }}>
|
|
175
|
+
{`${((response().time - props.instance.request.time) / 1000).toFixed(2)}s`}
|
|
176
|
+
</Text>
|
|
177
|
+
</span>)}
|
|
178
|
+
</Show>
|
|
155
179
|
<IconButton onClick={props.onDelete}>
|
|
156
180
|
<TrashIcon title="Delete instance"/>
|
|
157
181
|
</IconButton>
|
|
@@ -180,18 +204,8 @@ export function ServerFunctionViewer(props) {
|
|
|
180
204
|
return (<Show when={props.show}>
|
|
181
205
|
<div data-start-dev-toolbar-panel>
|
|
182
206
|
<div data-start-functions-viewer>
|
|
183
|
-
{/*
|
|
184
|
-
<
|
|
185
|
-
{value => (<Show when={props.instances[value()]}>
|
|
186
|
-
{instance => (<ServerFunctionInstanceViewer id={value()} instance={instance()} onReturn={() => {
|
|
187
|
-
setCurrentInstance(undefined);
|
|
188
|
-
}} onDelete={() => {
|
|
189
|
-
props.onDeleteInstance(value());
|
|
190
|
-
}}/>)}
|
|
191
|
-
</Show>)}
|
|
192
|
-
</Show>
|
|
193
|
-
<Show when={!currentInstance()}>
|
|
194
|
-
{/* list of calls */}
|
|
207
|
+
{/* list of calls */}
|
|
208
|
+
<div data-start-functions-sidebar>
|
|
195
209
|
<div data-start-functions-nav>
|
|
196
210
|
<FunctionIcon title="Server functions"/>
|
|
197
211
|
<Text options={{ size: "sm" }}>Server functions</Text>
|
|
@@ -209,7 +223,20 @@ export function ServerFunctionViewer(props) {
|
|
|
209
223
|
</Select>
|
|
210
224
|
</Show>
|
|
211
225
|
</div>
|
|
212
|
-
</
|
|
226
|
+
</div>
|
|
227
|
+
{/* request/response viewer */}
|
|
228
|
+
<div data-start-functions-detail>
|
|
229
|
+
<Show when={currentInstance()} fallback={<Placeholder>
|
|
230
|
+
<Text options={{ size: "xs" }}>Select a server function call.</Text>
|
|
231
|
+
</Placeholder>}>
|
|
232
|
+
{value => (<Show when={props.instances[value()]}>
|
|
233
|
+
{instance => (<ServerFunctionInstanceViewer id={value()} instance={instance()} onDelete={() => {
|
|
234
|
+
setCurrentInstance(undefined);
|
|
235
|
+
props.onDeleteInstance(value());
|
|
236
|
+
}}/>)}
|
|
237
|
+
</Show>)}
|
|
238
|
+
</Show>
|
|
239
|
+
</div>
|
|
213
240
|
</div>
|
|
214
241
|
</div>
|
|
215
242
|
</Show>);
|
|
@@ -2,21 +2,51 @@
|
|
|
2
2
|
display: flex;
|
|
3
3
|
align-items: center;
|
|
4
4
|
gap: 0.5rem;
|
|
5
|
+
|
|
6
|
+
min-width: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
[data-start-functions-instance-detail] > [data-start-text-size] {
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
text-overflow: ellipsis;
|
|
5
12
|
}
|
|
6
13
|
|
|
7
14
|
[data-start-functions-viewer] {
|
|
8
|
-
color:
|
|
15
|
+
color: var(--start-dt-text);
|
|
16
|
+
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: row;
|
|
19
|
+
|
|
20
|
+
height: 100%;
|
|
21
|
+
}
|
|
9
22
|
|
|
23
|
+
[data-start-functions-sidebar] {
|
|
10
24
|
display: flex;
|
|
11
25
|
flex-direction: column;
|
|
12
26
|
|
|
13
|
-
|
|
27
|
+
width: 17rem;
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
min-height: 0;
|
|
30
|
+
|
|
31
|
+
border-right: var(--start-dt-border-soft) 1px solid;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
[data-start-functions-detail] {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
|
|
38
|
+
flex: 1;
|
|
39
|
+
min-width: 0;
|
|
40
|
+
min-height: 0;
|
|
41
|
+
|
|
42
|
+
overflow: auto;
|
|
14
43
|
}
|
|
15
44
|
|
|
16
45
|
[data-start-functions-instances-container] {
|
|
17
|
-
color:
|
|
46
|
+
color: var(--start-dt-text);
|
|
18
47
|
width: 100%;
|
|
19
|
-
|
|
48
|
+
flex: 1;
|
|
49
|
+
min-height: 0;
|
|
20
50
|
overflow: auto;
|
|
21
51
|
}
|
|
22
52
|
|
|
@@ -31,8 +61,12 @@
|
|
|
31
61
|
display: flex;
|
|
32
62
|
align-items: center;
|
|
33
63
|
justify-content: space-between;
|
|
34
|
-
|
|
35
|
-
|
|
64
|
+
gap: 0.5rem;
|
|
65
|
+
padding: 0.5rem 0.75rem;
|
|
66
|
+
color: var(--start-dt-text);
|
|
67
|
+
font-family:
|
|
68
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
|
69
|
+
monospace;
|
|
36
70
|
}
|
|
37
71
|
|
|
38
72
|
[data-start-headers] {
|
|
@@ -60,16 +94,21 @@
|
|
|
60
94
|
gap: 0.25rem;
|
|
61
95
|
}
|
|
62
96
|
|
|
97
|
+
[data-start-property] > [data-start-text-weight="semibold"] {
|
|
98
|
+
color: var(--start-dt-text-muted);
|
|
99
|
+
}
|
|
100
|
+
|
|
63
101
|
[data-start-function-instance-viewer] {
|
|
64
102
|
display: flex;
|
|
65
103
|
flex-direction: column;
|
|
66
104
|
|
|
67
105
|
width: 100%;
|
|
106
|
+
min-height: 100%;
|
|
68
107
|
}
|
|
69
108
|
|
|
70
109
|
[data-start-function-instance-viewer-nav],
|
|
71
110
|
[data-start-functions-nav] {
|
|
72
|
-
padding: 0.5rem;
|
|
111
|
+
padding: 0.5rem 0.75rem;
|
|
73
112
|
display: flex;
|
|
74
113
|
align-items: center;
|
|
75
114
|
gap: 0.5rem;
|
|
@@ -78,32 +117,126 @@
|
|
|
78
117
|
|
|
79
118
|
position: sticky;
|
|
80
119
|
top: 0;
|
|
120
|
+
z-index: 1;
|
|
121
|
+
|
|
122
|
+
border-bottom: var(--start-dt-border-soft) 1px solid;
|
|
81
123
|
|
|
82
|
-
|
|
124
|
+
background: var(--start-dt-bg-glass);
|
|
125
|
+
backdrop-filter: blur(16px) saturate(140%);
|
|
126
|
+
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
|
127
|
+
}
|
|
83
128
|
|
|
84
|
-
|
|
129
|
+
[data-start-functions-nav] {
|
|
130
|
+
justify-content: flex-start;
|
|
131
|
+
flex-shrink: 0;
|
|
85
132
|
}
|
|
86
133
|
|
|
87
134
|
[data-start-functions-nav] svg {
|
|
88
135
|
padding: 0.25rem;
|
|
136
|
+
color: var(--start-dt-accent);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
[data-start-function-instance-viewer-nav] > div:last-child {
|
|
140
|
+
display: flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
gap: 0.5rem;
|
|
143
|
+
|
|
144
|
+
flex-shrink: 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
[data-start-function-instance-timing] {
|
|
148
|
+
display: inline-flex;
|
|
149
|
+
align-items: center;
|
|
150
|
+
|
|
151
|
+
color: var(--start-dt-text-muted);
|
|
152
|
+
background: var(--start-dt-surface);
|
|
153
|
+
border-radius: 9999px;
|
|
154
|
+
padding: 0.125rem 0.5rem;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/* Body section (the only non-collapsible <div> section in a tab panel) fills the pane;
|
|
158
|
+
the minimum keeps it inspectable even when Headers/Information are expanded — the
|
|
159
|
+
tab panel scrolls instead of squeezing the body. */
|
|
160
|
+
[data-start-tab-panel] > div[data-start-section]:first-child {
|
|
161
|
+
flex: 1 1 auto;
|
|
162
|
+
min-height: 18rem;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
[data-start-tab-panel] > div[data-start-section]:first-child > [data-start-section-content] {
|
|
166
|
+
flex: 1;
|
|
167
|
+
min-height: 0;
|
|
89
168
|
}
|
|
90
169
|
|
|
91
170
|
[data-start-function-instance-viewer-nav-left] {
|
|
92
171
|
display: flex;
|
|
93
172
|
align-items: center;
|
|
94
173
|
gap: 0.5rem;
|
|
174
|
+
|
|
175
|
+
min-width: 0;
|
|
95
176
|
}
|
|
96
177
|
|
|
97
178
|
[data-start-function-instance-viewer-nav-left] > div {
|
|
98
179
|
display: flex;
|
|
99
180
|
align-items: center;
|
|
100
181
|
gap: 0.5rem;
|
|
182
|
+
|
|
183
|
+
min-width: 0;
|
|
101
184
|
}
|
|
102
185
|
|
|
103
186
|
[data-start-function-instance-viewer-content] {
|
|
104
|
-
|
|
187
|
+
flex: 1;
|
|
188
|
+
min-height: 0;
|
|
105
189
|
}
|
|
106
190
|
|
|
107
191
|
[data-start-function-instance-viewer-content] > [tc-tab-group] {
|
|
108
192
|
height: 100%;
|
|
193
|
+
|
|
194
|
+
display: flex;
|
|
195
|
+
flex-direction: column;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* shared key-value table (headers, form data, url search params) */
|
|
199
|
+
[data-start-kv-table] {
|
|
200
|
+
display: flex;
|
|
201
|
+
flex-direction: column;
|
|
202
|
+
gap: 0;
|
|
203
|
+
|
|
204
|
+
border: 1px var(--start-dt-border-soft) solid;
|
|
205
|
+
border-radius: 0.5rem;
|
|
206
|
+
overflow: hidden;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
[data-start-kv-row] {
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: baseline;
|
|
212
|
+
gap: 0.75rem;
|
|
213
|
+
|
|
214
|
+
padding: 0.375rem 0.625rem;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
[data-start-kv-row]:nth-child(even) {
|
|
218
|
+
background-color: oklch(1 0 0 / 0.03);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
[data-start-kv-row]:hover {
|
|
222
|
+
background-color: var(--start-dt-surface-hover);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
[data-start-kv-key] {
|
|
226
|
+
flex: 0 0 11rem;
|
|
227
|
+
min-width: 0;
|
|
228
|
+
|
|
229
|
+
overflow: hidden;
|
|
230
|
+
text-overflow: ellipsis;
|
|
231
|
+
|
|
232
|
+
color: oklch(0.78 0.1 305);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
[data-start-kv-value] {
|
|
236
|
+
flex: 1;
|
|
237
|
+
min-width: 0;
|
|
238
|
+
|
|
239
|
+
word-break: break-all;
|
|
240
|
+
|
|
241
|
+
color: var(--start-dt-text);
|
|
109
242
|
}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
[data-start-dev-toolbar] {
|
|
2
|
+
/* design tokens — inherited by every panel and ui component inside */
|
|
3
|
+
--start-dt-bg: oklch(0.16 0.015 265);
|
|
4
|
+
--start-dt-bg-glass: oklch(0.17 0.015 265 / 0.88);
|
|
5
|
+
--start-dt-surface: oklch(0.22 0.02 265);
|
|
6
|
+
--start-dt-surface-hover: oklch(0.27 0.025 265);
|
|
7
|
+
--start-dt-surface-active: oklch(0.3 0.03 265);
|
|
8
|
+
--start-dt-border: oklch(0.34 0.02 265);
|
|
9
|
+
--start-dt-border-soft: oklch(0.27 0.02 265);
|
|
10
|
+
--start-dt-text: oklch(0.93 0.005 265);
|
|
11
|
+
--start-dt-text-muted: oklch(0.68 0.015 265);
|
|
12
|
+
--start-dt-accent: oklch(0.68 0.13 245);
|
|
13
|
+
--start-dt-accent-soft: oklch(0.68 0.13 245 / 0.16);
|
|
14
|
+
--start-dt-danger: oklch(0.63 0.21 25);
|
|
15
|
+
--start-dt-shadow: 0 12px 32px oklch(0 0 0 / 0.4), 0 2px 8px oklch(0 0 0 / 0.25);
|
|
16
|
+
|
|
2
17
|
position: fixed;
|
|
3
18
|
|
|
4
19
|
bottom: 0px;
|
|
@@ -8,19 +23,31 @@
|
|
|
8
23
|
flex-direction: column-reverse;
|
|
9
24
|
align-items: flex-start;
|
|
10
25
|
|
|
26
|
+
z-index: 2147483647;
|
|
27
|
+
|
|
28
|
+
color: var(--start-dt-text);
|
|
29
|
+
font-family:
|
|
30
|
+
system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol",
|
|
31
|
+
"Noto Color Emoji";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
[data-start-dev-toolbar] > [tc-toolbar] {
|
|
11
35
|
cursor: grab;
|
|
12
36
|
}
|
|
13
37
|
|
|
14
|
-
[data-start-dev-toolbar]:active {
|
|
38
|
+
[data-start-dev-toolbar] > [tc-toolbar]:active {
|
|
15
39
|
cursor: grabbing;
|
|
16
40
|
}
|
|
17
41
|
|
|
18
42
|
[data-start-dev-toolbar] > [tc-toolbar] {
|
|
19
43
|
position: relative;
|
|
20
44
|
|
|
21
|
-
background:
|
|
45
|
+
background: var(--start-dt-bg-glass);
|
|
46
|
+
backdrop-filter: blur(16px) saturate(140%);
|
|
47
|
+
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
|
48
|
+
|
|
22
49
|
margin: 1rem;
|
|
23
|
-
padding: 0.
|
|
50
|
+
padding: 0.375rem 0.625rem;
|
|
24
51
|
|
|
25
52
|
overflow: hidden;
|
|
26
53
|
border-radius: 9999px;
|
|
@@ -29,9 +56,10 @@
|
|
|
29
56
|
flex-direction: row;
|
|
30
57
|
align-items: center;
|
|
31
58
|
|
|
32
|
-
gap: 0.
|
|
59
|
+
gap: 0.625rem;
|
|
33
60
|
|
|
34
|
-
border:
|
|
61
|
+
border: var(--start-dt-border) 1px solid;
|
|
62
|
+
box-shadow: var(--start-dt-shadow);
|
|
35
63
|
}
|
|
36
64
|
|
|
37
65
|
[data-start-dev-toolbar] > [tc-toolbar] > div {
|
|
@@ -40,25 +68,30 @@
|
|
|
40
68
|
flex-direction: row;
|
|
41
69
|
align-items: center;
|
|
42
70
|
justify-content: center;
|
|
71
|
+
|
|
72
|
+
gap: 0.125rem;
|
|
43
73
|
}
|
|
44
74
|
|
|
45
75
|
[data-start-dev-toolbar] > [tc-toolbar] > div:last-child {
|
|
46
|
-
border-left:
|
|
47
|
-
padding-left: 0.
|
|
76
|
+
border-left: var(--start-dt-border) 1px solid;
|
|
77
|
+
padding-left: 0.625rem;
|
|
48
78
|
|
|
49
79
|
gap: 0.5rem;
|
|
80
|
+
|
|
81
|
+
color: var(--start-dt-text-muted);
|
|
50
82
|
}
|
|
51
83
|
|
|
52
84
|
[data-start-dev-toolbar-version] {
|
|
53
85
|
border-radius: 9999px;
|
|
54
|
-
color:
|
|
86
|
+
color: var(--start-dt-accent);
|
|
87
|
+
background: var(--start-dt-accent-soft);
|
|
55
88
|
padding: 0.125rem 0.5rem;
|
|
56
89
|
|
|
57
90
|
font-size: 0.875rem;
|
|
58
91
|
line-height: 1.25rem;
|
|
59
92
|
font-weight: 600;
|
|
60
93
|
|
|
61
|
-
border:
|
|
94
|
+
border: none;
|
|
62
95
|
}
|
|
63
96
|
|
|
64
97
|
[data-start-dev-toolbar-version] > div {
|
|
@@ -72,14 +105,21 @@
|
|
|
72
105
|
}
|
|
73
106
|
|
|
74
107
|
[data-start-dev-toolbar-panel] {
|
|
75
|
-
border:
|
|
76
|
-
background:
|
|
108
|
+
border: var(--start-dt-border) 1px solid;
|
|
109
|
+
background: var(--start-dt-bg-glass);
|
|
110
|
+
backdrop-filter: blur(16px) saturate(140%);
|
|
111
|
+
-webkit-backdrop-filter: blur(16px) saturate(140%);
|
|
112
|
+
box-shadow: var(--start-dt-shadow);
|
|
113
|
+
|
|
77
114
|
margin: 0rem 1rem;
|
|
78
115
|
|
|
79
|
-
overflow:
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
|
|
118
|
+
display: flex;
|
|
119
|
+
flex-direction: column;
|
|
80
120
|
|
|
81
|
-
width:
|
|
82
|
-
height:
|
|
121
|
+
width: 56rem;
|
|
122
|
+
height: min(40rem, calc(100vh - 4rem));
|
|
83
123
|
|
|
84
124
|
max-width: calc(100vw - 10rem);
|
|
85
125
|
max-height: calc(100vh - 2rem);
|
|
@@ -19,6 +19,8 @@ export function DevToolbar(props) {
|
|
|
19
19
|
createEffect(() => {
|
|
20
20
|
const current = ref();
|
|
21
21
|
if (current) {
|
|
22
|
+
// Only the toolbar pill itself is the drag handle — panels/popovers are not draggable.
|
|
23
|
+
const handle = current.querySelector(":scope > [tc-toolbar]") ?? current;
|
|
22
24
|
let isDown = false;
|
|
23
25
|
// Offsets of the mouse relatively to the element's position
|
|
24
26
|
let offsetX = 0;
|
|
@@ -35,7 +37,7 @@ export function DevToolbar(props) {
|
|
|
35
37
|
};
|
|
36
38
|
let isDirty = false;
|
|
37
39
|
const ac = new AbortController();
|
|
38
|
-
|
|
40
|
+
handle.addEventListener("mousedown", e => {
|
|
39
41
|
isDown = true;
|
|
40
42
|
const rect = current.getBoundingClientRect();
|
|
41
43
|
currentX = rect.left;
|
|
@@ -111,9 +113,14 @@ export function DevToolbar(props) {
|
|
|
111
113
|
}
|
|
112
114
|
pushError(error.error ?? error);
|
|
113
115
|
};
|
|
116
|
+
const onRejectionEvent = (event) => {
|
|
117
|
+
pushError(event.reason);
|
|
118
|
+
};
|
|
114
119
|
window.addEventListener("error", onErrorEvent);
|
|
120
|
+
window.addEventListener("unhandledrejection", onRejectionEvent);
|
|
115
121
|
onCleanup(() => {
|
|
116
122
|
window.removeEventListener("error", onErrorEvent);
|
|
123
|
+
window.removeEventListener("unhandledrejection", onRejectionEvent);
|
|
117
124
|
});
|
|
118
125
|
});
|
|
119
126
|
const [store, setStore] = createStore({
|
package/dist/shared/ui/Badge.css
CHANGED
|
@@ -5,29 +5,40 @@
|
|
|
5
5
|
gap: 0.25rem;
|
|
6
6
|
|
|
7
7
|
border-radius: 0.375rem;
|
|
8
|
-
padding: 0.125rem 0.
|
|
8
|
+
padding: 0.125rem 0.375rem;
|
|
9
|
+
|
|
10
|
+
font-size: 0.75rem;
|
|
11
|
+
line-height: 1rem;
|
|
12
|
+
font-weight: 600;
|
|
13
|
+
font-family:
|
|
14
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New",
|
|
15
|
+
monospace;
|
|
9
16
|
|
|
10
17
|
background-color: var(--background);
|
|
11
|
-
border: 1px var(--
|
|
18
|
+
border: 1px var(--border) solid;
|
|
12
19
|
color: var(--foreground);
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
[data-start-badge="success"] {
|
|
16
|
-
--background: oklch(
|
|
17
|
-
--
|
|
23
|
+
--background: oklch(0.63 0.15 150 / 0.14);
|
|
24
|
+
--border: oklch(0.63 0.15 150 / 0.4);
|
|
25
|
+
--foreground: oklch(0.8 0.14 152);
|
|
18
26
|
}
|
|
19
27
|
|
|
20
28
|
[data-start-badge="failure"] {
|
|
21
|
-
--background: oklch(
|
|
22
|
-
--
|
|
29
|
+
--background: oklch(0.63 0.21 25 / 0.14);
|
|
30
|
+
--border: oklch(0.63 0.21 25 / 0.4);
|
|
31
|
+
--foreground: oklch(0.78 0.15 22);
|
|
23
32
|
}
|
|
24
33
|
|
|
25
34
|
[data-start-badge="warning"] {
|
|
26
|
-
--background: oklch(
|
|
27
|
-
--
|
|
35
|
+
--background: oklch(0.75 0.15 85 / 0.14);
|
|
36
|
+
--border: oklch(0.75 0.15 85 / 0.4);
|
|
37
|
+
--foreground: oklch(0.85 0.13 88);
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
[data-start-badge="info"] {
|
|
31
|
-
--background: oklch(
|
|
32
|
-
--
|
|
41
|
+
--background: oklch(0.68 0.13 245 / 0.14);
|
|
42
|
+
--border: oklch(0.68 0.13 245 / 0.4);
|
|
43
|
+
--foreground: oklch(0.78 0.11 245);
|
|
33
44
|
}
|