termcast 1.3.46 → 1.3.47
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/build.d.ts.map +1 -1
- package/dist/build.js +12 -3
- package/dist/build.js.map +1 -1
- package/dist/components/actions.d.ts +18 -0
- package/dist/components/actions.d.ts.map +1 -1
- package/dist/components/actions.js +70 -5
- package/dist/components/actions.js.map +1 -1
- package/dist/components/detail.d.ts.map +1 -1
- package/dist/components/detail.js +3 -1
- package/dist/components/detail.js.map +1 -1
- package/dist/components/dropdown.d.ts.map +1 -1
- package/dist/components/dropdown.js +40 -11
- package/dist/components/dropdown.js.map +1 -1
- package/dist/components/form/dropdown.d.ts.map +1 -1
- package/dist/components/form/dropdown.js +26 -10
- package/dist/components/form/dropdown.js.map +1 -1
- package/dist/components/list.d.ts +7 -0
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +82 -15
- package/dist/components/list.js.map +1 -1
- package/dist/components/metadata.d.ts.map +1 -1
- package/dist/components/metadata.js +2 -1
- package/dist/components/metadata.js.map +1 -1
- package/dist/components/spinner.d.ts +6 -0
- package/dist/components/spinner.d.ts.map +1 -0
- package/dist/components/spinner.js +12 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/examples/action-shortcut.d.ts +2 -0
- package/dist/examples/action-shortcut.d.ts.map +1 -0
- package/dist/examples/action-shortcut.js +20 -0
- package/dist/examples/action-shortcut.js.map +1 -0
- package/dist/examples/internal/scrollbox-with-descendants.js +19 -8
- package/dist/examples/internal/scrollbox-with-descendants.js.map +1 -1
- package/dist/examples/list-spacing-default.d.ts +5 -0
- package/dist/examples/list-spacing-default.d.ts.map +1 -0
- package/dist/examples/list-spacing-default.js +10 -0
- package/dist/examples/list-spacing-default.js.map +1 -0
- package/dist/examples/list-spacing-mode.d.ts +10 -0
- package/dist/examples/list-spacing-mode.d.ts.map +1 -0
- package/dist/examples/list-spacing-mode.js +26 -0
- package/dist/examples/list-spacing-mode.js.map +1 -0
- package/dist/examples/list-spacing-relaxed.d.ts +5 -0
- package/dist/examples/list-spacing-relaxed.d.ts.map +1 -0
- package/dist/examples/list-spacing-relaxed.js +10 -0
- package/dist/examples/list-spacing-relaxed.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/state.d.ts +9 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +2 -0
- package/dist/state.js.map +1 -1
- package/package.json +3 -3
- package/src/build.tsx +12 -3
- package/src/components/actions.tsx +77 -5
- package/src/components/detail.tsx +3 -1
- package/src/components/dropdown.tsx +49 -11
- package/src/components/form/dropdown.tsx +32 -10
- package/src/components/list.tsx +157 -18
- package/src/components/metadata.tsx +3 -2
- package/src/components/spinner.tsx +25 -0
- package/src/examples/action-shortcut.tsx +53 -0
- package/src/examples/action-shortcut.vitest.tsx +178 -0
- package/src/examples/actions-context.vitest.tsx +4 -4
- package/src/examples/detail-metadata-showcase.vitest.tsx +17 -3
- package/src/examples/form-dropdown.vitest.tsx +8 -8
- package/src/examples/form-tagpicker.vitest.tsx +4 -4
- package/src/examples/github.vitest.tsx +16 -9
- package/src/examples/internal/scrollbox-with-descendants.tsx +27 -8
- package/src/examples/list-detail-metadata.vitest.tsx +3 -1
- package/src/examples/list-loading-empty-view.vitest.tsx +5 -5
- package/src/examples/list-scrollbox.vitest.tsx +5 -5
- package/src/examples/list-spacing-default.tsx +38 -0
- package/src/examples/list-spacing-mode.tsx +137 -0
- package/src/examples/list-spacing-mode.vitest.tsx +158 -0
- package/src/examples/list-spacing-relaxed.tsx +38 -0
- package/src/examples/list-with-detail.vitest.tsx +63 -28
- package/src/examples/list-with-sections.vitest.tsx +13 -13
- package/src/examples/simple-file-picker.vitest.tsx +1 -1
- package/src/examples/simple-grid.vitest.tsx +42 -35
- package/src/examples/simple-navigation.vitest.tsx +14 -14
- package/src/extensions/dev.vitest.tsx +9 -3
- package/src/index.tsx +2 -0
- package/src/state.tsx +13 -0
|
@@ -8,7 +8,7 @@ beforeEach(async () => {
|
|
|
8
8
|
command: 'bun',
|
|
9
9
|
args: ['src/examples/list-with-detail.tsx'],
|
|
10
10
|
cols: 80,
|
|
11
|
-
rows:
|
|
11
|
+
rows: 33,
|
|
12
12
|
})
|
|
13
13
|
})
|
|
14
14
|
|
|
@@ -58,7 +58,10 @@ test('list with detail view display and navigation', async () => {
|
|
|
58
58
|
│
|
|
59
59
|
│
|
|
60
60
|
│ Types
|
|
61
|
-
|
|
61
|
+
│
|
|
62
|
+
│ Grass
|
|
63
|
+
│
|
|
64
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
62
65
|
|
|
63
66
|
"
|
|
64
67
|
`)
|
|
@@ -97,7 +100,10 @@ test('list with detail view display and navigation', async () => {
|
|
|
97
100
|
│
|
|
98
101
|
│
|
|
99
102
|
│ Types
|
|
100
|
-
|
|
103
|
+
│
|
|
104
|
+
│ Grass
|
|
105
|
+
│
|
|
106
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
101
107
|
|
|
102
108
|
"
|
|
103
109
|
`)
|
|
@@ -134,7 +140,10 @@ test('list with detail view display and navigation', async () => {
|
|
|
134
140
|
│
|
|
135
141
|
│
|
|
136
142
|
│ Types
|
|
137
|
-
|
|
143
|
+
│
|
|
144
|
+
│ Fire
|
|
145
|
+
│
|
|
146
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
138
147
|
|
|
139
148
|
"
|
|
140
149
|
`)
|
|
@@ -170,11 +179,14 @@ test('list with detail view display and navigation', async () => {
|
|
|
170
179
|
│ See Console Logs │
|
|
171
180
|
│ │
|
|
172
181
|
│ │
|
|
182
|
+
│ │
|
|
183
|
+
│ │
|
|
184
|
+
│ │
|
|
173
185
|
│ ↵ select ↑↓ navigate │
|
|
174
186
|
│ │
|
|
175
187
|
╰──────────────────────────────────────────────────────────────────────────╯
|
|
176
|
-
│
|
|
177
|
-
↵ toggle detail ↑↓ navigate ^k a │
|
|
188
|
+
│
|
|
189
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
178
190
|
|
|
179
191
|
"
|
|
180
192
|
`)
|
|
@@ -217,6 +229,9 @@ test('list with detail view display and navigation', async () => {
|
|
|
217
229
|
|
|
218
230
|
|
|
219
231
|
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
220
235
|
"
|
|
221
236
|
`)
|
|
222
237
|
|
|
@@ -257,7 +272,10 @@ test('list with detail view display and navigation', async () => {
|
|
|
257
272
|
│
|
|
258
273
|
│
|
|
259
274
|
│ Types
|
|
260
|
-
|
|
275
|
+
│
|
|
276
|
+
│ Fire
|
|
277
|
+
│
|
|
278
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
261
279
|
|
|
262
280
|
"
|
|
263
281
|
`)
|
|
@@ -306,7 +324,10 @@ test('list detail view search functionality', async () => {
|
|
|
306
324
|
│
|
|
307
325
|
│
|
|
308
326
|
│ Types
|
|
309
|
-
|
|
327
|
+
│
|
|
328
|
+
│ Fire
|
|
329
|
+
│
|
|
330
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
310
331
|
|
|
311
332
|
"
|
|
312
333
|
`)
|
|
@@ -332,27 +353,30 @@ test('list detail view search functionality', async () => {
|
|
|
332
353
|
> water
|
|
333
354
|
|
|
334
355
|
|
|
335
|
-
│
|
|
336
|
-
No items found │
|
|
356
|
+
│ wartortle ▲
|
|
357
|
+
No items found │ █
|
|
337
358
|
│ Illustration
|
|
338
359
|
│
|
|
339
360
|
│ Types
|
|
340
361
|
│
|
|
341
|
-
│
|
|
362
|
+
│ Water
|
|
342
363
|
│
|
|
343
364
|
│ Characteristics
|
|
344
365
|
│
|
|
345
|
-
│ - Height:
|
|
346
|
-
│ - Weight:
|
|
366
|
+
│ - Height: 1m
|
|
367
|
+
│ - Weight: 22.5kg
|
|
347
368
|
│
|
|
348
369
|
│ Abilities
|
|
349
370
|
│
|
|
350
|
-
│ -
|
|
351
|
-
│ -
|
|
371
|
+
│ - Torrent
|
|
372
|
+
│ - Rain Dish
|
|
352
373
|
│
|
|
353
374
|
│
|
|
354
375
|
│ Types
|
|
355
|
-
|
|
376
|
+
│
|
|
377
|
+
│ Water
|
|
378
|
+
│
|
|
379
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
356
380
|
|
|
357
381
|
"
|
|
358
382
|
`)
|
|
@@ -369,27 +393,30 @@ test('list detail view search functionality', async () => {
|
|
|
369
393
|
> water
|
|
370
394
|
|
|
371
395
|
|
|
372
|
-
│
|
|
373
|
-
No items found │
|
|
396
|
+
│ wartortle ▲
|
|
397
|
+
No items found │ █
|
|
374
398
|
│ Illustration
|
|
375
399
|
│
|
|
376
400
|
│ Types
|
|
377
401
|
│
|
|
378
|
-
│
|
|
402
|
+
│ Water
|
|
379
403
|
│
|
|
380
404
|
│ Characteristics
|
|
381
405
|
│
|
|
382
|
-
│ - Height:
|
|
383
|
-
│ - Weight:
|
|
406
|
+
│ - Height: 1m
|
|
407
|
+
│ - Weight: 22.5kg
|
|
384
408
|
│
|
|
385
409
|
│ Abilities
|
|
386
410
|
│
|
|
387
|
-
│ -
|
|
388
|
-
│ -
|
|
411
|
+
│ - Torrent
|
|
412
|
+
│ - Rain Dish
|
|
389
413
|
│
|
|
390
414
|
│
|
|
391
415
|
│ Types
|
|
392
|
-
|
|
416
|
+
│
|
|
417
|
+
│ Water
|
|
418
|
+
│
|
|
419
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
393
420
|
|
|
394
421
|
"
|
|
395
422
|
`)
|
|
@@ -438,7 +465,10 @@ test('list detail metadata rendering', async () => {
|
|
|
438
465
|
│
|
|
439
466
|
│
|
|
440
467
|
│ Types
|
|
441
|
-
|
|
468
|
+
│
|
|
469
|
+
│ Grass
|
|
470
|
+
│
|
|
471
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
442
472
|
|
|
443
473
|
"
|
|
444
474
|
`)
|
|
@@ -482,7 +512,10 @@ test('list detail metadata rendering', async () => {
|
|
|
482
512
|
│
|
|
483
513
|
│
|
|
484
514
|
│ Types
|
|
485
|
-
|
|
515
|
+
│
|
|
516
|
+
│ Water
|
|
517
|
+
│
|
|
518
|
+
↵ toggle detail ↑↓ navigate ^k a │ ───────────────────────────────── ▼
|
|
486
519
|
|
|
487
520
|
"
|
|
488
521
|
`)
|
|
@@ -502,7 +535,8 @@ test('list with detail layout consistency - short vs long detail content', async
|
|
|
502
535
|
waitFor: (text) => {
|
|
503
536
|
return (
|
|
504
537
|
text.includes('›Short Detail') &&
|
|
505
|
-
text.includes('Brief content')
|
|
538
|
+
text.includes('Brief content') &&
|
|
539
|
+
text.includes('↑↓ navigate')
|
|
506
540
|
)
|
|
507
541
|
},
|
|
508
542
|
})
|
|
@@ -514,7 +548,8 @@ test('list with detail layout consistency - short vs long detail content', async
|
|
|
514
548
|
waitFor: (text) => {
|
|
515
549
|
return (
|
|
516
550
|
text.includes('›Long Detail') &&
|
|
517
|
-
text.includes('extensive')
|
|
551
|
+
text.includes('extensive') &&
|
|
552
|
+
text.includes('↑↓ navigate')
|
|
518
553
|
)
|
|
519
554
|
},
|
|
520
555
|
})
|
|
@@ -440,8 +440,6 @@ test('list actions panel with ctrl+k', async () => {
|
|
|
440
440
|
"
|
|
441
441
|
|
|
442
442
|
|
|
443
|
-
Simple List Example ────────────────────────────────────────────
|
|
444
|
-
|
|
445
443
|
╭────────────────────────────────────────────────────────────────╮
|
|
446
444
|
│ │
|
|
447
445
|
│ Actions esc │
|
|
@@ -456,8 +454,10 @@ test('list actions panel with ctrl+k', async () => {
|
|
|
456
454
|
│ See Console Logs │
|
|
457
455
|
│ │
|
|
458
456
|
│ │
|
|
459
|
-
│
|
|
460
|
-
│ │
|
|
457
|
+
│ │
|
|
458
|
+
│ │
|
|
459
|
+
│ │
|
|
460
|
+
│ ↵ select ↑↓ navigate │"
|
|
461
461
|
`)
|
|
462
462
|
|
|
463
463
|
// Navigate down to second action
|
|
@@ -468,8 +468,6 @@ test('list actions panel with ctrl+k', async () => {
|
|
|
468
468
|
"
|
|
469
469
|
|
|
470
470
|
|
|
471
|
-
Simple List Example ────────────────────────────────────────────
|
|
472
|
-
|
|
473
471
|
╭────────────────────────────────────────────────────────────────╮
|
|
474
472
|
│ │
|
|
475
473
|
│ Actions esc │
|
|
@@ -484,8 +482,10 @@ test('list actions panel with ctrl+k', async () => {
|
|
|
484
482
|
│ See Console Logs │
|
|
485
483
|
│ │
|
|
486
484
|
│ │
|
|
487
|
-
│
|
|
488
|
-
│ │
|
|
485
|
+
│ │
|
|
486
|
+
│ │
|
|
487
|
+
│ │
|
|
488
|
+
│ ↵ select ↑↓ navigate │"
|
|
489
489
|
`)
|
|
490
490
|
|
|
491
491
|
// Trigger the second action (Add to Cart)
|
|
@@ -706,15 +706,15 @@ test('list scrollbox scrolling with sections', async () => {
|
|
|
706
706
|
|
|
707
707
|
> Search items...
|
|
708
708
|
|
|
709
|
+
Fruits
|
|
710
|
+
Apple Red and sweet Fresh [Popular]
|
|
711
|
+
Banana Yellow and nutritious Ripe
|
|
709
712
|
Orange Citrus and juicy Fresh
|
|
710
713
|
Grape Sweet clusters [Seasonal]
|
|
711
714
|
Mango Tropical delight Imported
|
|
712
715
|
Pineapple Sweet and tangy
|
|
713
716
|
›Strawberry Red and sweet [Popular]
|
|
714
717
|
|
|
715
|
-
Vegetables
|
|
716
|
-
Carrot Orange and crunchy [Healthy]
|
|
717
|
-
Lettuce Green and fresh
|
|
718
718
|
|
|
719
719
|
|
|
720
720
|
↑↓ navigate ^k actions
|
|
@@ -736,8 +736,6 @@ test('list scrollbox scrolling with sections', async () => {
|
|
|
736
736
|
|
|
737
737
|
> Search items...
|
|
738
738
|
|
|
739
|
-
|
|
740
|
-
Vegetables
|
|
741
739
|
Carrot Orange and crunchy [Healthy]
|
|
742
740
|
Lettuce Green and fresh
|
|
743
741
|
›Broccoli Green florets [Healthy]
|
|
@@ -746,6 +744,8 @@ test('list scrollbox scrolling with sections', async () => {
|
|
|
746
744
|
Cucumber Cool and crisp
|
|
747
745
|
Bell Pepper Colorful and crunchy [Fresh]
|
|
748
746
|
|
|
747
|
+
Bread Freshly baked Today [New]
|
|
748
|
+
|
|
749
749
|
|
|
750
750
|
↑↓ navigate ^k actions
|
|
751
751
|
|
|
@@ -51,6 +51,7 @@ test('file picker shows form fields', async () => {
|
|
|
51
51
|
└
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
ctrl ↵ submit tab navigate ^k actions
|
|
54
55
|
|
|
55
56
|
|
|
56
57
|
|
|
@@ -76,7 +77,6 @@ test('file picker shows form fields', async () => {
|
|
|
76
77
|
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
ctrl ↵ submit tab navigate ^k actions
|
|
80
80
|
|
|
81
81
|
"
|
|
82
82
|
`)
|
|
@@ -137,7 +137,6 @@ test('grid navigation and display', async () => {
|
|
|
137
137
|
Simple Grid Example ────────────────────────────────────────────
|
|
138
138
|
|
|
139
139
|
> Search items...
|
|
140
|
-
|
|
141
140
|
╭────────────────────────────────────────────────────────────────╮
|
|
142
141
|
│ │
|
|
143
142
|
│ Actions esc │
|
|
@@ -152,11 +151,12 @@ test('grid navigation and display', async () => {
|
|
|
152
151
|
│ See Console Logs │
|
|
153
152
|
│ │
|
|
154
153
|
│ │
|
|
154
|
+
│ │
|
|
155
|
+
│ │
|
|
156
|
+
│ │
|
|
155
157
|
│ ↵ select ↑↓ navigate │
|
|
156
158
|
│ │
|
|
157
|
-
╰────────────────────────────────────────────────────────────────╯
|
|
158
|
-
|
|
159
|
-
"
|
|
159
|
+
╰────────────────────────────────────────────────────────────────╯"
|
|
160
160
|
`)
|
|
161
161
|
|
|
162
162
|
// Close actions with escape
|
|
@@ -522,7 +522,6 @@ test('grid mouse interaction', async () => {
|
|
|
522
522
|
Simple Grid Example ────────────────────────────────────────────
|
|
523
523
|
|
|
524
524
|
> Search items...
|
|
525
|
-
|
|
526
525
|
╭────────────────────────────────────────────────────────────────╮
|
|
527
526
|
│ │
|
|
528
527
|
│ Actions esc │
|
|
@@ -537,23 +536,31 @@ test('grid mouse interaction', async () => {
|
|
|
537
536
|
│ See Console Logs │
|
|
538
537
|
│ │
|
|
539
538
|
│ │
|
|
539
|
+
│ │
|
|
540
|
+
│ │
|
|
541
|
+
│ │
|
|
540
542
|
│ ↵ select ↑↓ navigate │
|
|
541
543
|
│ │
|
|
542
|
-
╰────────────────────────────────────────────────────────────────╯
|
|
543
|
-
|
|
544
|
-
"
|
|
544
|
+
╰────────────────────────────────────────────────────────────────╯"
|
|
545
545
|
`)
|
|
546
546
|
|
|
547
547
|
// Close the actions panel first
|
|
548
548
|
await session.press('esc')
|
|
549
549
|
|
|
550
|
-
// Navigate back up to make Apple visible
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
550
|
+
// Navigate back up to make Apple visible.
|
|
551
|
+
// Grid is implemented via List, which uses edge-triggered pagination.
|
|
552
|
+
// Pressing up a fixed small number of times can leave the viewport unchanged.
|
|
553
|
+
// Overshooting is safe since List doesn't wrap at the top boundary.
|
|
554
|
+
for (let i = 0; i < 30; i++) {
|
|
555
|
+
await session.press('up')
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
await session.text({
|
|
559
|
+
waitFor: (text) => {
|
|
560
|
+
return text.includes('Apple')
|
|
561
|
+
},
|
|
562
|
+
timeout: 5000,
|
|
563
|
+
})
|
|
557
564
|
|
|
558
565
|
// Click on "Apple" to go back to first section
|
|
559
566
|
await session.click('Apple', { first: true })
|
|
@@ -566,25 +573,25 @@ test('grid mouse interaction', async () => {
|
|
|
566
573
|
Simple Grid Example ────────────────────────────────────────────
|
|
567
574
|
|
|
568
575
|
> Search items...
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
576
|
+
╭────────────────────────────────────────────────────────────────╮
|
|
577
|
+
│ │
|
|
578
|
+
│ Actions esc │
|
|
579
|
+
│ │
|
|
580
|
+
│ > Search actions... │
|
|
581
|
+
│ │
|
|
582
|
+
│ ›Show Details │
|
|
583
|
+
│ Copy Emoji ⌃C │
|
|
584
|
+
│ │
|
|
585
|
+
│ Settings │
|
|
586
|
+
│ Change Theme... │
|
|
587
|
+
│ See Console Logs │
|
|
588
|
+
│ │
|
|
589
|
+
│ │
|
|
590
|
+
│ │
|
|
591
|
+
│ │
|
|
592
|
+
│ │
|
|
593
|
+
│ ↵ select ↑↓ navigate │
|
|
594
|
+
│ │
|
|
595
|
+
╰────────────────────────────────────────────────────────────────╯"
|
|
589
596
|
`)
|
|
590
597
|
}, 10000)
|
|
@@ -295,7 +295,6 @@ test('navigation with actions panel', async () => {
|
|
|
295
295
|
expect(actionsOpenSnapshot).toMatchInlineSnapshot(`
|
|
296
296
|
"
|
|
297
297
|
|
|
298
|
-
|
|
299
298
|
╭────────────────────────────────────────────────────────────────╮
|
|
300
299
|
│ │
|
|
301
300
|
│ Actions esc │
|
|
@@ -310,14 +309,15 @@ test('navigation with actions panel', async () => {
|
|
|
310
309
|
│ See Console Logs │
|
|
311
310
|
│ │
|
|
312
311
|
│ │
|
|
312
|
+
│ │
|
|
313
|
+
│ │
|
|
314
|
+
│ │
|
|
313
315
|
│ ↵ select ↑↓ navigate │
|
|
314
316
|
│ │
|
|
315
317
|
╰────────────────────────────────────────────────────────────────╯
|
|
316
318
|
|
|
317
319
|
|
|
318
320
|
|
|
319
|
-
|
|
320
|
-
|
|
321
321
|
"
|
|
322
322
|
`)
|
|
323
323
|
|
|
@@ -328,7 +328,6 @@ test('navigation with actions panel', async () => {
|
|
|
328
328
|
expect(secondActionSnapshot).toMatchInlineSnapshot(`
|
|
329
329
|
"
|
|
330
330
|
|
|
331
|
-
|
|
332
331
|
╭────────────────────────────────────────────────────────────────╮
|
|
333
332
|
│ │
|
|
334
333
|
│ Actions esc │
|
|
@@ -343,14 +342,15 @@ test('navigation with actions panel', async () => {
|
|
|
343
342
|
│ See Console Logs │
|
|
344
343
|
│ │
|
|
345
344
|
│ │
|
|
345
|
+
│ │
|
|
346
|
+
│ │
|
|
347
|
+
│ │
|
|
346
348
|
│ ↵ select ↑↓ navigate │
|
|
347
349
|
│ │
|
|
348
350
|
╰────────────────────────────────────────────────────────────────╯
|
|
349
351
|
|
|
350
352
|
|
|
351
353
|
|
|
352
|
-
|
|
353
|
-
|
|
354
354
|
"
|
|
355
355
|
`)
|
|
356
356
|
|
|
@@ -439,7 +439,6 @@ test('navigation with actions panel', async () => {
|
|
|
439
439
|
expect(detailActionsSnapshot).toMatchInlineSnapshot(`
|
|
440
440
|
"
|
|
441
441
|
|
|
442
|
-
|
|
443
442
|
╭────────────────────────────────────────────────────────────────╮
|
|
444
443
|
│ │
|
|
445
444
|
│ Actions esc │
|
|
@@ -454,14 +453,15 @@ test('navigation with actions panel', async () => {
|
|
|
454
453
|
│ See Console Logs │
|
|
455
454
|
│ │
|
|
456
455
|
│ │
|
|
456
|
+
│ │
|
|
457
|
+
│ │
|
|
458
|
+
│ │
|
|
457
459
|
│ ↵ select ↑↓ navigate │
|
|
458
460
|
│ │
|
|
459
461
|
╰────────────────────────────────────────────────────────────────╯
|
|
460
462
|
|
|
461
463
|
|
|
462
464
|
|
|
463
|
-
|
|
464
|
-
|
|
465
465
|
"
|
|
466
466
|
`)
|
|
467
467
|
|
|
@@ -525,12 +525,12 @@ test('search functionality in main and detail views', async () => {
|
|
|
525
525
|
|
|
526
526
|
Navigation Example ─────────────────────────────────────────────
|
|
527
527
|
|
|
528
|
-
>
|
|
528
|
+
> second
|
|
529
|
+
|
|
530
|
+
›Second Item Navigate to second detail
|
|
531
|
+
|
|
532
|
+
|
|
529
533
|
|
|
530
|
-
Items
|
|
531
|
-
›First Item Navigate to first detail
|
|
532
|
-
Second Item Navigate to second detail
|
|
533
|
-
Third Item Navigate to third detail
|
|
534
534
|
|
|
535
535
|
|
|
536
536
|
|
|
@@ -93,7 +93,6 @@ test('selecting command with arguments shows arguments form', async () => {
|
|
|
93
93
|
|
|
94
94
|
> Search commands...
|
|
95
95
|
|
|
96
|
-
Google Oauth view
|
|
97
96
|
usePromise Demo Shows how to use the usePromise h view
|
|
98
97
|
Show State Shows the current application state in view
|
|
99
98
|
›With Arguments Demonstrates command arguments (te view
|
|
@@ -101,6 +100,7 @@ test('selecting command with arguments shows arguments form', async () => {
|
|
|
101
100
|
Throw Error Command that throws an error at root view
|
|
102
101
|
|
|
103
102
|
|
|
103
|
+
|
|
104
104
|
↵ run command ↑↓ navigate ^k actions
|
|
105
105
|
"
|
|
106
106
|
`)
|
|
@@ -161,6 +161,7 @@ test('can fill arguments and run command', async () => {
|
|
|
161
161
|
|
|
162
162
|
// Type in the search query field
|
|
163
163
|
await session.type('my search term')
|
|
164
|
+
await session.waitIdle()
|
|
164
165
|
|
|
165
166
|
const afterTypingSnapshot = await session.text()
|
|
166
167
|
expect(afterTypingSnapshot).toMatchInlineSnapshot(`
|
|
@@ -183,9 +184,14 @@ test('can fill arguments and run command', async () => {
|
|
|
183
184
|
"
|
|
184
185
|
`)
|
|
185
186
|
|
|
186
|
-
// Submit via
|
|
187
|
+
// Submit via actions dialog.
|
|
188
|
+
// Terminals don't reliably encode Ctrl+Enter, but Ctrl+K is stable.
|
|
187
189
|
await session.press(['ctrl', 'k'])
|
|
188
|
-
await
|
|
190
|
+
await waitForTextWithDebug({
|
|
191
|
+
session,
|
|
192
|
+
waitFor: (text) => text.includes('Search actions...') && text.includes('Run Command'),
|
|
193
|
+
timeout: 10000,
|
|
194
|
+
})
|
|
189
195
|
await session.press('enter')
|
|
190
196
|
|
|
191
197
|
await waitForTextWithDebug({
|
package/src/index.tsx
CHANGED
|
@@ -9,6 +9,7 @@ export { List, Grid } from 'termcast/src/components/list'
|
|
|
9
9
|
export { List as default } from 'termcast/src/components/list'
|
|
10
10
|
export type {
|
|
11
11
|
ListProps,
|
|
12
|
+
ListSpacingMode,
|
|
12
13
|
ItemProps as ListItemProps,
|
|
13
14
|
SectionProps as ListSectionProps,
|
|
14
15
|
DetailProps as ListDetailProps,
|
|
@@ -143,6 +144,7 @@ export type {
|
|
|
143
144
|
|
|
144
145
|
// Icons and Images
|
|
145
146
|
export { Icon, getIconEmoji, getIconShape, IconComponent } from 'termcast/src/components/icon'
|
|
147
|
+
export { Spinner } from 'termcast/src/components/spinner'
|
|
146
148
|
import {
|
|
147
149
|
Image as ImageComponent,
|
|
148
150
|
ImageMask,
|
package/src/state.tsx
CHANGED
|
@@ -2,6 +2,14 @@ import { create } from 'zustand'
|
|
|
2
2
|
import { type ReactNode } from 'react'
|
|
3
3
|
import type { TextareaRenderable } from '@opentui/core'
|
|
4
4
|
import type { RaycastPackageJson } from './package-json'
|
|
5
|
+
import type { KeyboardKeyEquivalent, KeyboardKeyModifier } from 'termcast/src/keyboard'
|
|
6
|
+
|
|
7
|
+
// Registered action shortcuts for global keyboard handling
|
|
8
|
+
// Stored by ActionPanel, consumed by List/Detail/Form keyboard handlers
|
|
9
|
+
export interface RegisteredActionShortcut {
|
|
10
|
+
shortcut: { modifiers?: KeyboardKeyModifier[]; key: KeyboardKeyEquivalent }
|
|
11
|
+
execute: () => void
|
|
12
|
+
}
|
|
5
13
|
|
|
6
14
|
// Toast action keyboard shortcuts (ctrl+t for primary, ctrl+g for secondary)
|
|
7
15
|
export const toastPrimaryActionKey = { ctrl: true, name: 't' } as const
|
|
@@ -73,6 +81,9 @@ interface AppState {
|
|
|
73
81
|
currentThemeName: string
|
|
74
82
|
// Active search input ref - used to clear search before exiting on ESC
|
|
75
83
|
activeSearchInputRef: TextareaRenderable | null
|
|
84
|
+
// Registered action shortcuts for global keyboard handling
|
|
85
|
+
// ActionPanel populates this, List/Detail/Form consume it
|
|
86
|
+
registeredActionShortcuts: RegisteredActionShortcut[]
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
export const useStore = create<AppState>(() => ({
|
|
@@ -101,4 +112,6 @@ export const useStore = create<AppState>(() => ({
|
|
|
101
112
|
currentThemeName: 'termcast',
|
|
102
113
|
// Active search input ref
|
|
103
114
|
activeSearchInputRef: null,
|
|
115
|
+
// Registered action shortcuts
|
|
116
|
+
registeredActionShortcuts: [],
|
|
104
117
|
}))
|