lynx-console 0.0.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/assets/src/components/BottomSheet.css.ts.vanilla-D-1A77Ik.css +83 -0
- package/dist/assets/src/components/ConsolePanel.css.ts.vanilla-B3avfSlI.css +246 -0
- package/dist/assets/src/components/FloatingButton.css.ts.vanilla-rPj35oLW.css +55 -0
- package/dist/assets/src/components/NetworkPanel.css.ts.vanilla-DFMduT0T.css +247 -0
- package/dist/assets/src/components/PerformancePanel.css.ts.vanilla-D35LuXlW.css +216 -0
- package/dist/assets/src/components/Tabs.css.ts.vanilla-DD7L2oXt.css +50 -0
- package/dist/index.cjs +1058 -0
- package/dist/index.css +466 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +17 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1059 -0
- package/dist/index.mjs.map +1 -0
- package/dist/setup.cjs +377 -0
- package/dist/setup.d.cts +15 -0
- package/dist/setup.d.cts.map +1 -0
- package/dist/setup.d.mts +15 -0
- package/dist/setup.d.mts.map +1 -0
- package/dist/setup.mjs +374 -0
- package/dist/setup.mjs.map +1 -0
- package/package.json +51 -0
- package/src/components/BottomSheet.css.ts +93 -0
- package/src/components/BottomSheet.tsx +142 -0
- package/src/components/ConsolePanel.css.ts +261 -0
- package/src/components/ConsolePanel.tsx +41 -0
- package/src/components/FloatingButton.css.ts +62 -0
- package/src/components/FloatingButton.tsx +37 -0
- package/src/components/LogPanel.tsx +241 -0
- package/src/components/NetworkDetailSection.tsx +42 -0
- package/src/components/NetworkPanel.css.ts +280 -0
- package/src/components/NetworkPanel.tsx +222 -0
- package/src/components/PerformancePanel.css.ts +224 -0
- package/src/components/PerformancePanel.tsx +209 -0
- package/src/components/Tabs.css.ts +66 -0
- package/src/components/Tabs.tsx +81 -0
- package/src/globals.d.ts +9 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/useConsole.ts +35 -0
- package/src/hooks/useNetwork.ts +36 -0
- package/src/hooks/usePerformance.ts +39 -0
- package/src/index.tsx +110 -0
- package/src/setup/_setupMainThreadConsole.ts +80 -0
- package/src/setup/index.ts +4 -0
- package/src/setup/setupLogMonitor.ts +78 -0
- package/src/setup/setupMainThreadConsole.ts +34 -0
- package/src/setup/setupNetworkMonitor.ts +247 -0
- package/src/setup/setupPerformanceMonitor.ts +70 -0
- package/src/shared/ensureConsoleStructure.ts +20 -0
- package/src/styles/getDimensionValue.ts +7 -0
- package/src/styles/global.css.ts +10 -0
- package/src/styles/tokens.json +80 -0
- package/src/styles/typography.ts +25 -0
- package/src/styles/vars/color.ts +228 -0
- package/src/styles/vars/dimension.ts +79 -0
- package/src/styles/vars/index.css +463 -0
- package/src/styles/vars/index.ts +22 -0
- package/src/styles/vars/radius.ts +12 -0
- package/src/types.ts +96 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from "@lynx-js/react";
|
|
2
|
+
import type { BaseEvent, InputInputEvent, NodesRef } from "@lynx-js/types";
|
|
3
|
+
import { stringify } from "javascript-stringify";
|
|
4
|
+
import type { LogEntry } from "../types";
|
|
5
|
+
import * as css from "./ConsolePanel.css";
|
|
6
|
+
|
|
7
|
+
interface LogPanelProps {
|
|
8
|
+
logs: LogEntry[];
|
|
9
|
+
clearLogs: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const runCode = (code: string) => {
|
|
13
|
+
try {
|
|
14
|
+
// biome-ignore lint: intentional REPL tool
|
|
15
|
+
const result = eval(code);
|
|
16
|
+
if (result instanceof Promise) {
|
|
17
|
+
result.then((r) => console.log(r)).catch((e) => console.error(e));
|
|
18
|
+
} else {
|
|
19
|
+
console.log(result);
|
|
20
|
+
}
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error(e);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
|
|
27
|
+
const [expandedArgs, setExpandedArgs] = useState(new Set());
|
|
28
|
+
const [code, setCode] = useState("");
|
|
29
|
+
const inputRef = useRef<NodesRef>(null);
|
|
30
|
+
const listRef = useRef<NodesRef>(null);
|
|
31
|
+
const logsRef = useRef(logs);
|
|
32
|
+
logsRef.current = logs;
|
|
33
|
+
|
|
34
|
+
const scrollToBottom = (smooth: boolean) => {
|
|
35
|
+
if (logsRef.current.length === 0) return;
|
|
36
|
+
listRef.current
|
|
37
|
+
?.invoke({
|
|
38
|
+
method: "scrollToPosition",
|
|
39
|
+
params: { position: logsRef.current.length - 1, smooth },
|
|
40
|
+
})
|
|
41
|
+
.exec();
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
scrollToBottom(true);
|
|
46
|
+
}, [logs]);
|
|
47
|
+
|
|
48
|
+
const toggleArg = (key: string) => {
|
|
49
|
+
setExpandedArgs((prev) => {
|
|
50
|
+
const next = new Set(prev);
|
|
51
|
+
if (next.has(key)) {
|
|
52
|
+
next.delete(key);
|
|
53
|
+
} else {
|
|
54
|
+
next.add(key);
|
|
55
|
+
}
|
|
56
|
+
return next;
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleRun = () => {
|
|
61
|
+
const trimmed = code.trim();
|
|
62
|
+
if (!trimmed) return;
|
|
63
|
+
|
|
64
|
+
setCode("");
|
|
65
|
+
inputRef.current
|
|
66
|
+
?.invoke({ method: "setValue", params: { value: "" } })
|
|
67
|
+
.exec();
|
|
68
|
+
runCode(trimmed);
|
|
69
|
+
setTimeout(() => scrollToBottom(false), 100);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const renderArg = (
|
|
73
|
+
arg: unknown,
|
|
74
|
+
parentKey: string,
|
|
75
|
+
level: "log" | "info" | "warn" | "error",
|
|
76
|
+
): React.ReactNode => {
|
|
77
|
+
const key = parentKey;
|
|
78
|
+
const isExpanded = expandedArgs.has(key);
|
|
79
|
+
|
|
80
|
+
if (arg === null) {
|
|
81
|
+
return <text className={css.argNull}>null</text>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (arg === undefined) {
|
|
85
|
+
return <text className={css.argUndefined}>undefined</text>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (typeof arg === "string") {
|
|
89
|
+
const MAX_LENGTH = 80;
|
|
90
|
+
const shouldTruncate = arg.length > MAX_LENGTH;
|
|
91
|
+
|
|
92
|
+
if (!shouldTruncate) {
|
|
93
|
+
return <text className={css.argString({ level })}>{arg}</text>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 문자열이 길 경우 토글 버튼 추가
|
|
97
|
+
return (
|
|
98
|
+
<view className={css.argObject}>
|
|
99
|
+
<view className={css.argObjectHeader} bindtap={() => toggleArg(key)}>
|
|
100
|
+
<text className={css.toggleIndicator}>
|
|
101
|
+
{isExpanded ? "▼" : "▶"}
|
|
102
|
+
</text>
|
|
103
|
+
<text className={css.argString({ level })}>
|
|
104
|
+
{isExpanded ? arg : `${arg.slice(0, MAX_LENGTH)}...`}
|
|
105
|
+
</text>
|
|
106
|
+
</view>
|
|
107
|
+
</view>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (typeof arg === "number" || typeof arg === "boolean") {
|
|
112
|
+
return <text className={css.argPrimitive({ level })}>{String(arg)}</text>;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (typeof arg === "object") {
|
|
116
|
+
let preview = "Object";
|
|
117
|
+
if (Array.isArray(arg)) {
|
|
118
|
+
preview = `Array(${arg.length})`;
|
|
119
|
+
} else if (arg instanceof Map) {
|
|
120
|
+
preview = `Map(${arg.size})`;
|
|
121
|
+
} else if (arg instanceof Set) {
|
|
122
|
+
preview = `Set(${arg.size})`;
|
|
123
|
+
} else if (arg instanceof Date) {
|
|
124
|
+
preview = `Date`;
|
|
125
|
+
} else if (arg instanceof RegExp) {
|
|
126
|
+
preview = `RegExp`;
|
|
127
|
+
} else if (arg instanceof Error) {
|
|
128
|
+
preview = `${arg.constructor.name}`;
|
|
129
|
+
} else if (arg?.constructor?.name && arg.constructor.name !== "Object") {
|
|
130
|
+
preview = arg.constructor.name;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let jsonString: string;
|
|
134
|
+
if (arg instanceof Map) {
|
|
135
|
+
const entries = Array.from(arg.entries()).map(
|
|
136
|
+
([k, v]) => ` [${stringify(k)}, ${stringify(v)}]`,
|
|
137
|
+
);
|
|
138
|
+
jsonString = `{\n${entries.join(",\n")}\n}`;
|
|
139
|
+
} else if (arg instanceof Set) {
|
|
140
|
+
const values = Array.from(arg.values()).map((v) => stringify(v));
|
|
141
|
+
jsonString = `{\n${values.join(", ")}\n}`;
|
|
142
|
+
} else {
|
|
143
|
+
jsonString =
|
|
144
|
+
stringify(arg, null, 2, { references: true }) ?? String(arg);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<view className={css.argObject}>
|
|
149
|
+
<view className={css.argObjectHeader} bindtap={() => toggleArg(key)}>
|
|
150
|
+
<text className={css.toggleIndicator}>
|
|
151
|
+
{isExpanded ? "▼" : "▶"}
|
|
152
|
+
</text>
|
|
153
|
+
<text className={css.argObjectPreview}>{preview}</text>
|
|
154
|
+
</view>
|
|
155
|
+
{isExpanded && (
|
|
156
|
+
<view className={css.argObjectContent}>
|
|
157
|
+
<text className={css.argObjectJson}>{jsonString}</text>
|
|
158
|
+
</view>
|
|
159
|
+
)}
|
|
160
|
+
</view>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return <text className={css.argPrimitive({ level })}>{String(arg)}</text>;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<view className={css.logContainer}>
|
|
169
|
+
<view className={css.logHeader}>
|
|
170
|
+
<text className={css.logCount}>Total {logs.length} logs</text>
|
|
171
|
+
<view style={{ display: "flex", flexDirection: "row", gap: 8 }}>
|
|
172
|
+
<view className={css.clearButton} bindtap={clearLogs}>
|
|
173
|
+
<text className={css.clearButtonText}>Clear</text>
|
|
174
|
+
</view>
|
|
175
|
+
</view>
|
|
176
|
+
</view>
|
|
177
|
+
<list
|
|
178
|
+
ref={listRef}
|
|
179
|
+
scroll-orientation="vertical"
|
|
180
|
+
className={css.logList}
|
|
181
|
+
initial-scroll-index={Math.max(0, logs.length - 1)}
|
|
182
|
+
>
|
|
183
|
+
{logs.length === 0 ? (
|
|
184
|
+
<list-item item-key="empty-state">
|
|
185
|
+
<view className={css.placeholder}>
|
|
186
|
+
<text className={css.placeholderText}>
|
|
187
|
+
No logs yet. Try console.log("Hello!")
|
|
188
|
+
</text>
|
|
189
|
+
</view>
|
|
190
|
+
</list-item>
|
|
191
|
+
) : (
|
|
192
|
+
logs.map((log) => {
|
|
193
|
+
return (
|
|
194
|
+
<list-item key={log.id} item-key={log.id}>
|
|
195
|
+
<view className={css.logItem({ level: log.level })}>
|
|
196
|
+
<view className={css.logItemHeader}>
|
|
197
|
+
<text className={css.logLevel({ level: log.level })}>
|
|
198
|
+
{log.level.toUpperCase()}
|
|
199
|
+
</text>
|
|
200
|
+
<text className={css.logTime}>
|
|
201
|
+
{new Date(log.timestamp).toISOString()}
|
|
202
|
+
</text>
|
|
203
|
+
</view>
|
|
204
|
+
<view className={css.logArgsContainer}>
|
|
205
|
+
{log.args.map((arg, index) => (
|
|
206
|
+
<view
|
|
207
|
+
key={`${log.id}-${index.toString()}`}
|
|
208
|
+
className={css.logArgItem}
|
|
209
|
+
>
|
|
210
|
+
{renderArg(
|
|
211
|
+
arg,
|
|
212
|
+
`${log.id}-${index.toString()}`,
|
|
213
|
+
log.level,
|
|
214
|
+
)}
|
|
215
|
+
</view>
|
|
216
|
+
))}
|
|
217
|
+
</view>
|
|
218
|
+
</view>
|
|
219
|
+
</list-item>
|
|
220
|
+
);
|
|
221
|
+
})
|
|
222
|
+
)}
|
|
223
|
+
</list>
|
|
224
|
+
<view className={css.replInputRow}>
|
|
225
|
+
<text className={css.replPrompt}>{"›"}</text>
|
|
226
|
+
<input
|
|
227
|
+
ref={inputRef}
|
|
228
|
+
className={css.replInput}
|
|
229
|
+
placeholder="enter code..."
|
|
230
|
+
bindinput={(e: BaseEvent<"bindinput", InputInputEvent>) =>
|
|
231
|
+
setCode(e.detail.value)
|
|
232
|
+
}
|
|
233
|
+
bindconfirm={handleRun}
|
|
234
|
+
/>
|
|
235
|
+
<view className={css.replRunButton} bindtap={handleRun}>
|
|
236
|
+
<text className={css.replRunButtonText}>Run</text>
|
|
237
|
+
</view>
|
|
238
|
+
</view>
|
|
239
|
+
</view>
|
|
240
|
+
);
|
|
241
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as css from "./NetworkPanel.css";
|
|
2
|
+
|
|
3
|
+
interface NetworkDetailSectionProps {
|
|
4
|
+
headers?: Record<string, string> | undefined;
|
|
5
|
+
body?: string | undefined;
|
|
6
|
+
error?: string | undefined;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const NetworkDetailSection = ({
|
|
10
|
+
headers = {},
|
|
11
|
+
body = "",
|
|
12
|
+
error = "",
|
|
13
|
+
}: NetworkDetailSectionProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<>
|
|
16
|
+
{/* Headers */}
|
|
17
|
+
<view className={css.detailSection}>
|
|
18
|
+
<text className={css.detailSectionTitle}>Headers</text>
|
|
19
|
+
{headers && Object.keys(headers).length > 0 ? (
|
|
20
|
+
<view className={css.table}>
|
|
21
|
+
{Object.entries(headers).map(([key, value]) => (
|
|
22
|
+
<view key={key} className={css.tableRow}>
|
|
23
|
+
<text className={css.tableKey}>{key}</text>
|
|
24
|
+
<text className={css.tableValue}>{value}</text>
|
|
25
|
+
</view>
|
|
26
|
+
))}
|
|
27
|
+
</view>
|
|
28
|
+
) : (
|
|
29
|
+
<text className={css.emptyText}>No headers</text>
|
|
30
|
+
)}
|
|
31
|
+
</view>
|
|
32
|
+
|
|
33
|
+
{/* Body */}
|
|
34
|
+
<view className={css.detailSection}>
|
|
35
|
+
<text className={css.detailSectionTitle}>Body</text>
|
|
36
|
+
{error && <text className={css.errorText}>{error}</text>}
|
|
37
|
+
{body && <text className={css.bodyText}>{body}</text>}
|
|
38
|
+
{!error && !body && <text className={css.emptyText}>No body</text>}
|
|
39
|
+
</view>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { style } from "@vanilla-extract/css";
|
|
2
|
+
import { recipe } from "@vanilla-extract/recipes";
|
|
3
|
+
import { typography } from "../styles/typography";
|
|
4
|
+
import { vars } from "../styles/vars";
|
|
5
|
+
|
|
6
|
+
export const container = style({
|
|
7
|
+
display: "flex",
|
|
8
|
+
flexDirection: "column",
|
|
9
|
+
flex: 1,
|
|
10
|
+
paddingTop: 4,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const header = style({
|
|
14
|
+
display: "flex",
|
|
15
|
+
flexDirection: "row",
|
|
16
|
+
alignItems: "center",
|
|
17
|
+
justifyContent: "space-between",
|
|
18
|
+
marginBottom: 8,
|
|
19
|
+
paddingBottom: 4,
|
|
20
|
+
borderBottomWidth: 1,
|
|
21
|
+
borderBottomColor: vars.$color.stroke.neutralSubtle,
|
|
22
|
+
borderBottomStyle: "solid",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const count = style({
|
|
26
|
+
...typography("t3", "regular"),
|
|
27
|
+
color: vars.$color.fg.neutralSubtle,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const clearButton = style({
|
|
31
|
+
padding: "6px 12px",
|
|
32
|
+
backgroundColor: vars.$color.bg.neutralWeak,
|
|
33
|
+
borderRadius: 4,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
export const clearButtonText = style({
|
|
37
|
+
...typography("t3", "medium"),
|
|
38
|
+
color: vars.$color.fg.neutral,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const list = style({
|
|
42
|
+
flex: 1,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export const placeholder = style({
|
|
46
|
+
display: "flex",
|
|
47
|
+
alignItems: "center",
|
|
48
|
+
justifyContent: "center",
|
|
49
|
+
height: "100%",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export const placeholderText = style({
|
|
53
|
+
...typography("t4", "regular"),
|
|
54
|
+
color: vars.$color.fg.disabled,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export const item = recipe({
|
|
58
|
+
base: {
|
|
59
|
+
padding: "8px",
|
|
60
|
+
borderBottomWidth: 1,
|
|
61
|
+
borderBottomColor: vars.$color.stroke.neutralWeak,
|
|
62
|
+
borderBottomStyle: "solid",
|
|
63
|
+
},
|
|
64
|
+
variants: {
|
|
65
|
+
status: {
|
|
66
|
+
pending: {
|
|
67
|
+
backgroundColor: vars.$color.palette.gray100,
|
|
68
|
+
},
|
|
69
|
+
success: {},
|
|
70
|
+
error: {
|
|
71
|
+
backgroundColor: vars.$color.palette.red100,
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
export const itemHeader = style({
|
|
78
|
+
display: "flex",
|
|
79
|
+
flexDirection: "row",
|
|
80
|
+
alignItems: "center",
|
|
81
|
+
marginBottom: 4,
|
|
82
|
+
gap: 8,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
export const method = recipe({
|
|
86
|
+
base: {
|
|
87
|
+
...typography("t2", "bold"),
|
|
88
|
+
padding: "0 4px",
|
|
89
|
+
borderRadius: 2,
|
|
90
|
+
color: vars.$color.fg.neutral,
|
|
91
|
+
backgroundColor: vars.$color.bg.neutralWeak,
|
|
92
|
+
},
|
|
93
|
+
variants: {
|
|
94
|
+
type: {
|
|
95
|
+
GET: {
|
|
96
|
+
color: vars.$color.palette.blue600,
|
|
97
|
+
backgroundColor: vars.$color.palette.blue100,
|
|
98
|
+
},
|
|
99
|
+
POST: {
|
|
100
|
+
color: vars.$color.palette.green600,
|
|
101
|
+
backgroundColor: vars.$color.palette.green100,
|
|
102
|
+
},
|
|
103
|
+
PUT: {
|
|
104
|
+
color: vars.$color.palette.yellow600,
|
|
105
|
+
backgroundColor: vars.$color.palette.yellow100,
|
|
106
|
+
},
|
|
107
|
+
PATCH: {
|
|
108
|
+
color: vars.$color.palette.purple600,
|
|
109
|
+
backgroundColor: vars.$color.palette.purple100,
|
|
110
|
+
},
|
|
111
|
+
DELETE: {
|
|
112
|
+
color: vars.$color.palette.red600,
|
|
113
|
+
backgroundColor: vars.$color.palette.red100,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export const statusCode = recipe({
|
|
120
|
+
base: {
|
|
121
|
+
...typography("t2", "bold"),
|
|
122
|
+
},
|
|
123
|
+
variants: {
|
|
124
|
+
type: {
|
|
125
|
+
success: {
|
|
126
|
+
color: vars.$color.palette.green600,
|
|
127
|
+
},
|
|
128
|
+
error: {
|
|
129
|
+
color: vars.$color.palette.red600,
|
|
130
|
+
},
|
|
131
|
+
pending: {
|
|
132
|
+
color: vars.$color.fg.neutralSubtle,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export const time = style({
|
|
139
|
+
...typography("t2", "regular"),
|
|
140
|
+
color: vars.$color.fg.neutralSubtle,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
export const url = style({
|
|
144
|
+
...typography("t3", "regular"),
|
|
145
|
+
color: vars.$color.fg.neutral,
|
|
146
|
+
wordBreak: "break-all",
|
|
147
|
+
marginBottom: 4,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
export const path = style({
|
|
151
|
+
...typography("t3", "regular"),
|
|
152
|
+
color: vars.$color.fg.neutral,
|
|
153
|
+
wordBreak: "break-all",
|
|
154
|
+
whiteSpace: "pre-wrap",
|
|
155
|
+
overflow: "visible",
|
|
156
|
+
marginBottom: 4,
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
export const details = style({
|
|
160
|
+
...typography("t3", "regular"),
|
|
161
|
+
color: vars.$color.fg.neutralSubtle,
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
export const detailsContainer = style({
|
|
165
|
+
marginTop: 12,
|
|
166
|
+
paddingTop: 12,
|
|
167
|
+
borderTopWidth: 1,
|
|
168
|
+
borderTopColor: vars.$color.stroke.neutralSubtle,
|
|
169
|
+
borderTopStyle: "solid",
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
export const tabs = style({
|
|
173
|
+
display: "flex",
|
|
174
|
+
flexDirection: "row",
|
|
175
|
+
gap: 4,
|
|
176
|
+
paddingBottom: 6,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
export const tab = recipe({
|
|
180
|
+
base: {
|
|
181
|
+
padding: "4px 8px",
|
|
182
|
+
borderRadius: 4,
|
|
183
|
+
cursor: "pointer",
|
|
184
|
+
},
|
|
185
|
+
variants: {
|
|
186
|
+
active: {
|
|
187
|
+
true: {
|
|
188
|
+
backgroundColor: vars.$color.bg.neutralWeak,
|
|
189
|
+
},
|
|
190
|
+
false: {
|
|
191
|
+
backgroundColor: "transparent",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
export const tabText = recipe({
|
|
198
|
+
base: {
|
|
199
|
+
...typography("t4", "medium"),
|
|
200
|
+
},
|
|
201
|
+
variants: {
|
|
202
|
+
active: {
|
|
203
|
+
true: {
|
|
204
|
+
color: vars.$color.fg.neutral,
|
|
205
|
+
},
|
|
206
|
+
false: {
|
|
207
|
+
color: vars.$color.fg.neutralSubtle,
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
export const tabContent = style({
|
|
214
|
+
paddingTop: 8,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
export const detailSection = style({
|
|
218
|
+
marginBottom: 12,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
export const detailSectionTitle = style({
|
|
222
|
+
...typography("t3", "bold"),
|
|
223
|
+
color: vars.$color.fg.neutral,
|
|
224
|
+
marginBottom: 8,
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
export const table = style({
|
|
228
|
+
display: "flex",
|
|
229
|
+
flexDirection: "column",
|
|
230
|
+
gap: 4,
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
export const tableRow = style({
|
|
234
|
+
display: "flex",
|
|
235
|
+
flexDirection: "row",
|
|
236
|
+
gap: 8,
|
|
237
|
+
padding: "4px 8px",
|
|
238
|
+
backgroundColor: vars.$color.bg.neutralWeak,
|
|
239
|
+
borderRadius: 2,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
export const tableKey = style({
|
|
243
|
+
...typography("t3", "bold"),
|
|
244
|
+
color: vars.$color.fg.neutralSubtle,
|
|
245
|
+
minWidth: 70,
|
|
246
|
+
flexShrink: 0,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
export const tableValue = style({
|
|
250
|
+
...typography("t3", "regular"),
|
|
251
|
+
color: vars.$color.fg.neutral,
|
|
252
|
+
wordBreak: "break-all",
|
|
253
|
+
flex: 1,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
export const bodyText = style({
|
|
257
|
+
...typography("t3", "regular"),
|
|
258
|
+
color: vars.$color.fg.neutral,
|
|
259
|
+
padding: 8,
|
|
260
|
+
backgroundColor: vars.$color.bg.neutralWeak,
|
|
261
|
+
borderRadius: 4,
|
|
262
|
+
wordBreak: "break-all",
|
|
263
|
+
whiteSpace: "pre-wrap",
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
export const errorText = style({
|
|
267
|
+
...typography("t3", "regular"),
|
|
268
|
+
color: vars.$color.palette.red600,
|
|
269
|
+
padding: 8,
|
|
270
|
+
backgroundColor: vars.$color.palette.red100,
|
|
271
|
+
borderRadius: 4,
|
|
272
|
+
wordBreak: "break-all",
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
export const emptyText = style({
|
|
276
|
+
...typography("t3", "regular"),
|
|
277
|
+
color: vars.$color.fg.disabled,
|
|
278
|
+
textAlign: "center",
|
|
279
|
+
padding: "16px 0",
|
|
280
|
+
});
|