lynx-console 0.2.1 → 0.2.2

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.
@@ -1,6 +1,8 @@
1
1
  import { useEffect, useMemo, useRef, useState } from "@lynx-js/react";
2
2
  import type { BaseEvent, InputInputEvent, NodesRef } from "@lynx-js/types";
3
3
  import { stringify } from "javascript-stringify";
4
+ import { useThemeColors } from "../styles/ThemeContext";
5
+ import { type ThemeColors, fontWeight } from "../styles/theme";
4
6
  import type { LogEntry, LogLevel } from "../types";
5
7
  import "./ConsolePanel.css";
6
8
  import { FadeList } from "./FadeList";
@@ -32,7 +34,57 @@ const runCode = (code: string) => {
32
34
  }
33
35
  };
34
36
 
37
+ function getLevelColor(colors: ThemeColors, level: LogLevel): string {
38
+ switch (level) {
39
+ case "log":
40
+ return colors.palette.green600;
41
+ case "info":
42
+ return colors.palette.blue600;
43
+ case "warn":
44
+ return colors.palette.yellow600;
45
+ case "error":
46
+ return colors.palette.red600;
47
+ }
48
+ }
49
+
50
+ function getLogItemBg(
51
+ colors: ThemeColors,
52
+ level: LogLevel,
53
+ ): string | undefined {
54
+ switch (level) {
55
+ case "warn":
56
+ return colors.palette.yellow100;
57
+ case "error":
58
+ return colors.palette.red100;
59
+ default:
60
+ return undefined;
61
+ }
62
+ }
63
+
64
+ function getStringColor(colors: ThemeColors, level: LogLevel): string {
65
+ switch (level) {
66
+ case "warn":
67
+ return colors.palette.yellow900;
68
+ case "error":
69
+ return colors.palette.red900;
70
+ default:
71
+ return colors.fg.neutral;
72
+ }
73
+ }
74
+
75
+ function getPrimitiveColor(colors: ThemeColors, level: LogLevel): string {
76
+ switch (level) {
77
+ case "warn":
78
+ return colors.palette.yellow900;
79
+ case "error":
80
+ return colors.palette.red900;
81
+ default:
82
+ return colors.palette.blue600;
83
+ }
84
+ }
85
+
35
86
  export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
87
+ const colors = useThemeColors();
36
88
  const [expandedArgs, setExpandedArgs] = useState(new Set());
37
89
  const [code, setCode] = useState("");
38
90
  const [enabledLevels, setEnabledLevels] = useState<Set<LogLevel>>(
@@ -139,28 +191,50 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
139
191
  const isExpanded = expandedArgs.has(key);
140
192
 
141
193
  if (arg === null) {
142
- return <text className={"cp-argNull"}>null</text>;
194
+ return (
195
+ <text style={{ color: colors.fg.neutralSubtle, fontWeight: fontWeight.regular }}>
196
+ null
197
+ </text>
198
+ );
143
199
  }
144
200
 
145
201
  if (arg === undefined) {
146
- return <text className={"cp-argUndefined"}>undefined</text>;
202
+ return (
203
+ <text style={{ color: colors.fg.neutralSubtle, fontWeight: fontWeight.regular }}>
204
+ undefined
205
+ </text>
206
+ );
147
207
  }
148
208
 
149
209
  if (typeof arg === "string") {
150
210
  const MAX_LENGTH = 80;
151
211
  const shouldTruncate = arg.length > MAX_LENGTH;
212
+ const strColor = getStringColor(colors, level);
152
213
 
153
214
  if (!shouldTruncate) {
154
- return <text className={`cp-argString cp-argString--${level}`}>{arg}</text>;
215
+ return (
216
+ <text
217
+ className={"cp-argString"}
218
+ style={{ color: strColor, fontWeight: fontWeight.regular }}
219
+ >
220
+ {arg}
221
+ </text>
222
+ );
155
223
  }
156
224
 
157
225
  return (
158
226
  <view className={"cp-argObject"}>
159
227
  <view className={"cp-argObjectHeader"} bindtap={() => toggleArg(key)}>
160
- <text className={"cp-toggleIndicator"}>
228
+ <text
229
+ className={"cp-toggleIndicator"}
230
+ style={{ color: colors.fg.neutralSubtle, fontWeight: fontWeight.regular }}
231
+ >
161
232
  {isExpanded ? "▼" : "▶"}
162
233
  </text>
163
- <text className={`cp-argString cp-argString--${level}`}>
234
+ <text
235
+ className={"cp-argString"}
236
+ style={{ color: strColor, fontWeight: fontWeight.regular }}
237
+ >
164
238
  {isExpanded ? arg : `${arg.slice(0, MAX_LENGTH)}...`}
165
239
  </text>
166
240
  </view>
@@ -169,7 +243,14 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
169
243
  }
170
244
 
171
245
  if (typeof arg === "number" || typeof arg === "boolean") {
172
- return <text className={`cp-argPrimitive cp-argPrimitive--${level}`}>{String(arg)}</text>;
246
+ return (
247
+ <text
248
+ className={"cp-argPrimitive"}
249
+ style={{ color: getPrimitiveColor(colors, level), fontWeight: fontWeight.regular }}
250
+ >
251
+ {String(arg)}
252
+ </text>
253
+ );
173
254
  }
174
255
 
175
256
  if (typeof arg === "object") {
@@ -207,21 +288,41 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
207
288
  return (
208
289
  <view className={"cp-argObject"}>
209
290
  <view className={"cp-argObjectHeader"} bindtap={() => toggleArg(key)}>
210
- <text className={"cp-toggleIndicator"}>
291
+ <text
292
+ className={"cp-toggleIndicator"}
293
+ style={{ color: colors.fg.neutralSubtle, fontWeight: fontWeight.regular }}
294
+ >
211
295
  {isExpanded ? "▼" : "▶"}
212
296
  </text>
213
- <text className={"cp-argObjectPreview"}>{preview}</text>
297
+ <text
298
+ className={"cp-argObjectPreview"}
299
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.neutral }}
300
+ >
301
+ {preview}
302
+ </text>
214
303
  </view>
215
304
  {isExpanded && (
216
305
  <view className={"cp-argObjectContent"}>
217
- <text className={"cp-argObjectJson"}>{jsonString}</text>
306
+ <text
307
+ className={"cp-argObjectJson"}
308
+ style={{ fontWeight: fontWeight.regular, color: colors.fg.neutral }}
309
+ >
310
+ {jsonString}
311
+ </text>
218
312
  </view>
219
313
  )}
220
314
  </view>
221
315
  );
222
316
  }
223
317
 
224
- return <text className={`cp-argPrimitive cp-argPrimitive--${level}`}>{String(arg)}</text>;
318
+ return (
319
+ <text
320
+ className={"cp-argPrimitive"}
321
+ style={{ color: getPrimitiveColor(colors, level), fontWeight: fontWeight.regular }}
322
+ >
323
+ {String(arg)}
324
+ </text>
325
+ );
225
326
  };
226
327
 
227
328
  return (
@@ -233,22 +334,41 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
233
334
  <view className={"cp-filterWrapper"}>
234
335
  <view
235
336
  className={"cp-filterButton"}
337
+ style={{ backgroundColor: colors.bg.neutralWeak }}
236
338
  catchtap={() => setFilterOpen((v) => !v)}
237
339
  >
238
- <text className={"cp-filterButtonText"}>Filter ▼</text>
340
+ <text
341
+ className={"cp-filterButtonText"}
342
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.neutralMuted }}
343
+ >
344
+ Filter ▼
345
+ </text>
239
346
  </view>
240
347
  {filterOpen && (
241
- <view className={"cp-filterDropdown"} catchtap={() => {}}>
348
+ <view
349
+ className={"cp-filterDropdown"}
350
+ style={{
351
+ backgroundColor: colors.bg.layerFloating,
352
+ borderColor: colors.stroke.neutralSubtle,
353
+ }}
354
+ catchtap={() => {}}
355
+ >
242
356
  {LOG_LEVELS.map((level) => (
243
357
  <view
244
358
  key={level}
245
359
  className={"cp-filterOption"}
246
360
  bindtap={() => toggleLevel(level)}
247
361
  >
248
- <text className={`cp-filterCheckbox cp-filterCheckbox--${level}`}>
362
+ <text
363
+ className={"cp-filterCheckbox"}
364
+ style={{ fontWeight: fontWeight.medium, color: getLevelColor(colors, level) }}
365
+ >
249
366
  {enabledLevels.has(level) ? "✅" : "⬜"}
250
367
  </text>
251
- <text className={`cp-filterLabel cp-filterLabel--${level}`}>
368
+ <text
369
+ className={"cp-filterLabel"}
370
+ style={{ fontWeight: fontWeight.medium, color: getLevelColor(colors, level) }}
371
+ >
252
372
  {level.toUpperCase()}
253
373
  </text>
254
374
  </view>
@@ -256,11 +376,24 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
256
376
  </view>
257
377
  )}
258
378
  </view>
259
- <view className={"cp-searchWrapper"}>
260
- <text className={"cp-searchPrompt"}>{"›"}</text>
379
+ <view
380
+ className={"cp-searchWrapper"}
381
+ style={{ borderBottomColor: colors.stroke.neutralSubtle }}
382
+ >
383
+ <text
384
+ className={"cp-searchPrompt"}
385
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.placeholder }}
386
+ >
387
+ {"›"}
388
+ </text>
261
389
  <input
262
390
  ref={searchInputRef}
263
391
  className={"cp-searchInput"}
392
+ style={{
393
+ fontWeight: fontWeight.regular,
394
+ color: colors.fg.neutral,
395
+ caretColor: colors.palette.green600,
396
+ }}
264
397
  placeholder="Search logs..."
265
398
  bindinput={(e: BaseEvent<"bindinput", InputInputEvent>) =>
266
399
  setSearchQuery(e.detail.value)
@@ -276,13 +409,27 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
276
409
  .exec();
277
410
  }}
278
411
  >
279
- <text className={"cp-searchClearText"}>✕</text>
412
+ <text
413
+ className={"cp-searchClearText"}
414
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.placeholder }}
415
+ >
416
+
417
+ </text>
280
418
  </view>
281
419
  )}
282
420
  </view>
283
421
  <view style={{ display: "flex", flexDirection: "row", gap: 8 }}>
284
- <view className={"cp-clearButton"} bindtap={clearLogs}>
285
- <text className={"cp-clearButtonText"}>🗑</text>
422
+ <view
423
+ className={"cp-clearButton"}
424
+ style={{ backgroundColor: colors.bg.neutralWeak }}
425
+ bindtap={clearLogs}
426
+ >
427
+ <text
428
+ className={"cp-clearButtonText"}
429
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.neutralMuted }}
430
+ >
431
+ 🗑
432
+ </text>
286
433
  </view>
287
434
  </view>
288
435
  </view>
@@ -295,7 +442,10 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
295
442
  {filteredLogs.length === 0 ? (
296
443
  <list-item item-key="empty-state">
297
444
  <view className={"cp-placeholder"}>
298
- <text className={"cp-placeholderText"}>
445
+ <text
446
+ className={"cp-placeholderText"}
447
+ style={{ fontWeight: fontWeight.regular, color: colors.fg.disabled }}
448
+ >
299
449
  No logs yet. Try console.log("Hello!")
300
450
  </text>
301
451
  </view>
@@ -304,12 +454,30 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
304
454
  filteredLogs.map((log) => {
305
455
  return (
306
456
  <list-item key={log.id} item-key={log.id}>
307
- <view className={`cp-logItem cp-logItem--${log.level}`}>
457
+ <view
458
+ className={"cp-logItem"}
459
+ style={{
460
+ backgroundColor: getLogItemBg(colors, log.level),
461
+ borderBottomColor: colors.stroke.neutralWeak,
462
+ }}
463
+ >
308
464
  <view className={"cp-logItemHeader"}>
309
- <text className={`cp-logLevel cp-logLevel--${log.level}`}>
465
+ <text
466
+ className={"cp-logLevel"}
467
+ style={{
468
+ fontWeight: fontWeight.bold,
469
+ color: getLevelColor(colors, log.level),
470
+ }}
471
+ >
310
472
  {log.level.toUpperCase()}
311
473
  </text>
312
- <text className={"cp-logTime"}>
474
+ <text
475
+ className={"cp-logTime"}
476
+ style={{
477
+ fontWeight: fontWeight.regular,
478
+ color: colors.fg.neutralSubtle,
479
+ }}
480
+ >
313
481
  {new Date(log.timestamp).toISOString()}
314
482
  </text>
315
483
  </view>
@@ -318,6 +486,7 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
318
486
  <view
319
487
  key={`${log.id}-${index.toString()}`}
320
488
  className={"cp-logArgItem"}
489
+ style={{ fontWeight: fontWeight.regular }}
321
490
  >
322
491
  {renderArg(
323
492
  arg,
@@ -334,18 +503,37 @@ export const LogPanel = ({ logs, clearLogs }: LogPanelProps) => {
334
503
  )}
335
504
  </FadeList>
336
505
  <view className={"cp-replInputRow"}>
337
- <text className={"cp-replPrompt"}>{"›"}</text>
506
+ <text
507
+ className={"cp-replPrompt"}
508
+ style={{ fontWeight: fontWeight.medium, color: colors.fg.placeholder }}
509
+ >
510
+ {"›"}
511
+ </text>
338
512
  <input
339
513
  ref={inputRef}
340
514
  className={"cp-replInput"}
515
+ style={{
516
+ fontWeight: fontWeight.regular,
517
+ color: colors.fg.neutral,
518
+ caretColor: colors.palette.green600,
519
+ }}
341
520
  placeholder="enter code..."
342
521
  bindinput={(e: BaseEvent<"bindinput", InputInputEvent>) =>
343
522
  setCode(e.detail.value)
344
523
  }
345
524
  bindconfirm={handleRun}
346
525
  />
347
- <view className={"cp-replRunButton"} bindtap={handleRun}>
348
- <text className={"cp-replRunButtonText"}>Run</text>
526
+ <view
527
+ className={"cp-replRunButton"}
528
+ style={{ backgroundColor: colors.palette.green100 }}
529
+ bindtap={handleRun}
530
+ >
531
+ <text
532
+ className={"cp-replRunButtonText"}
533
+ style={{ fontWeight: fontWeight.medium, color: colors.palette.green600 }}
534
+ >
535
+ Run
536
+ </text>
349
537
  </view>
350
538
  </view>
351
539
  </view>
@@ -1,3 +1,5 @@
1
+ import { useThemeColors } from "../styles/ThemeContext";
2
+ import { fontWeight } from "../styles/theme";
1
3
  import "./NetworkPanel.css";
2
4
 
3
5
  interface NetworkDetailSectionProps {
@@ -11,31 +13,91 @@ export const NetworkDetailSection = ({
11
13
  body = "",
12
14
  error = "",
13
15
  }: NetworkDetailSectionProps) => {
16
+ const colors = useThemeColors();
17
+
14
18
  return (
15
19
  <>
16
20
  {/* Headers */}
17
21
  <view className={"np-detailSection"}>
18
- <text className={"np-detailSectionTitle"}>Headers</text>
22
+ <text
23
+ className={"np-detailSectionTitle"}
24
+ style={{ fontWeight: fontWeight.bold, color: colors.fg.neutral }}
25
+ >
26
+ Headers
27
+ </text>
19
28
  {headers && Object.keys(headers).length > 0 ? (
20
29
  <view className={"np-table"}>
21
30
  {Object.entries(headers).map(([key, value]) => (
22
- <view key={key} className={"np-tableRow"}>
23
- <text className={"np-tableKey"}>{key}</text>
24
- <text className={"np-tableValue"}>{value}</text>
31
+ <view
32
+ key={key}
33
+ className={"np-tableRow"}
34
+ style={{ backgroundColor: colors.bg.neutralWeak }}
35
+ >
36
+ <text
37
+ className={"np-tableKey"}
38
+ style={{ fontWeight: fontWeight.bold, color: colors.fg.neutralSubtle }}
39
+ >
40
+ {key}
41
+ </text>
42
+ <text
43
+ className={"np-tableValue"}
44
+ style={{ fontWeight: fontWeight.regular, color: colors.fg.neutral }}
45
+ >
46
+ {value}
47
+ </text>
25
48
  </view>
26
49
  ))}
27
50
  </view>
28
51
  ) : (
29
- <text className={"np-emptyText"}>No headers</text>
52
+ <text
53
+ className={"np-emptyText"}
54
+ style={{ fontWeight: fontWeight.regular, color: colors.fg.disabled }}
55
+ >
56
+ No headers
57
+ </text>
30
58
  )}
31
59
  </view>
32
60
 
33
61
  {/* Body */}
34
62
  <view className={"np-detailSection"}>
35
- <text className={"np-detailSectionTitle"}>Body</text>
36
- {error && <text className={"np-errorText"}>{error}</text>}
37
- {body && <text className={"np-bodyText"}>{body}</text>}
38
- {!error && !body && <text className={"np-emptyText"}>No body</text>}
63
+ <text
64
+ className={"np-detailSectionTitle"}
65
+ style={{ fontWeight: fontWeight.bold, color: colors.fg.neutral }}
66
+ >
67
+ Body
68
+ </text>
69
+ {error && (
70
+ <text
71
+ className={"np-errorText"}
72
+ style={{
73
+ fontWeight: fontWeight.regular,
74
+ color: colors.palette.red600,
75
+ backgroundColor: colors.palette.red100,
76
+ }}
77
+ >
78
+ {error}
79
+ </text>
80
+ )}
81
+ {body && (
82
+ <text
83
+ className={"np-bodyText"}
84
+ style={{
85
+ fontWeight: fontWeight.regular,
86
+ color: colors.fg.neutral,
87
+ backgroundColor: colors.bg.neutralWeak,
88
+ }}
89
+ >
90
+ {body}
91
+ </text>
92
+ )}
93
+ {!error && !body && (
94
+ <text
95
+ className={"np-emptyText"}
96
+ style={{ fontWeight: fontWeight.regular, color: colors.fg.disabled }}
97
+ >
98
+ No body
99
+ </text>
100
+ )}
39
101
  </view>
40
102
  </>
41
103
  );