termcast 1.3.50 → 1.3.52

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.
Files changed (178) hide show
  1. package/dist/apis/environment.d.ts +1 -0
  2. package/dist/apis/environment.d.ts.map +1 -1
  3. package/dist/apis/environment.js +5 -0
  4. package/dist/apis/environment.js.map +1 -1
  5. package/dist/app.d.ts +33 -0
  6. package/dist/app.d.ts.map +1 -0
  7. package/dist/app.js +1130 -0
  8. package/dist/app.js.map +1 -0
  9. package/dist/cli.js +80 -0
  10. package/dist/cli.js.map +1 -1
  11. package/dist/compile.d.ts.map +1 -1
  12. package/dist/compile.js +5 -2
  13. package/dist/compile.js.map +1 -1
  14. package/dist/components/actions.d.ts +4 -1
  15. package/dist/components/actions.d.ts.map +1 -1
  16. package/dist/components/actions.js +8 -5
  17. package/dist/components/actions.js.map +1 -1
  18. package/dist/components/detail.d.ts.map +1 -1
  19. package/dist/components/detail.js +21 -18
  20. package/dist/components/detail.js.map +1 -1
  21. package/dist/components/dropdown.d.ts.map +1 -1
  22. package/dist/components/dropdown.js +3 -2
  23. package/dist/components/dropdown.js.map +1 -1
  24. package/dist/components/footer.d.ts +6 -0
  25. package/dist/components/footer.d.ts.map +1 -1
  26. package/dist/components/footer.js +15 -6
  27. package/dist/components/footer.js.map +1 -1
  28. package/dist/components/form/checkbox.d.ts.map +1 -1
  29. package/dist/components/form/checkbox.js +1 -13
  30. package/dist/components/form/checkbox.js.map +1 -1
  31. package/dist/components/form/date-picker.js +2 -2
  32. package/dist/components/form/date-picker.js.map +1 -1
  33. package/dist/components/form/description.js +1 -1
  34. package/dist/components/form/description.js.map +1 -1
  35. package/dist/components/form/dropdown.d.ts.map +1 -1
  36. package/dist/components/form/dropdown.js +19 -3
  37. package/dist/components/form/dropdown.js.map +1 -1
  38. package/dist/components/form/file-picker.d.ts.map +1 -1
  39. package/dist/components/form/file-picker.js +22 -4
  40. package/dist/components/form/file-picker.js.map +1 -1
  41. package/dist/components/form/index.d.ts +3 -1
  42. package/dist/components/form/index.d.ts.map +1 -1
  43. package/dist/components/form/index.js +7 -5
  44. package/dist/components/form/index.js.map +1 -1
  45. package/dist/components/form/password-field.js +3 -3
  46. package/dist/components/form/password-field.js.map +1 -1
  47. package/dist/components/form/text-area.d.ts.map +1 -1
  48. package/dist/components/form/text-area.js +29 -6
  49. package/dist/components/form/text-area.js.map +1 -1
  50. package/dist/components/form/text-field.js +3 -3
  51. package/dist/components/form/text-field.js.map +1 -1
  52. package/dist/components/graph.d.ts.map +1 -1
  53. package/dist/components/graph.js +21 -25
  54. package/dist/components/graph.js.map +1 -1
  55. package/dist/components/heatmap.d.ts +80 -0
  56. package/dist/components/heatmap.d.ts.map +1 -0
  57. package/dist/components/heatmap.js +424 -0
  58. package/dist/components/heatmap.js.map +1 -0
  59. package/dist/components/list.d.ts +2 -0
  60. package/dist/components/list.d.ts.map +1 -1
  61. package/dist/components/list.js +91 -58
  62. package/dist/components/list.js.map +1 -1
  63. package/dist/components/markdown.d.ts +7 -0
  64. package/dist/components/markdown.d.ts.map +1 -0
  65. package/dist/components/markdown.js +19 -0
  66. package/dist/components/markdown.js.map +1 -0
  67. package/dist/components/metadata.d.ts.map +1 -1
  68. package/dist/components/metadata.js +4 -1
  69. package/dist/components/metadata.js.map +1 -1
  70. package/dist/components/progress-bar.d.ts +37 -0
  71. package/dist/components/progress-bar.d.ts.map +1 -0
  72. package/dist/components/progress-bar.js +34 -0
  73. package/dist/components/progress-bar.js.map +1 -0
  74. package/dist/components/table.d.ts +3 -2
  75. package/dist/components/table.d.ts.map +1 -1
  76. package/dist/components/table.js +78 -63
  77. package/dist/components/table.js.map +1 -1
  78. package/dist/diagram-parser.d.ts +17 -3
  79. package/dist/diagram-parser.d.ts.map +1 -1
  80. package/dist/diagram-parser.js +17 -3
  81. package/dist/diagram-parser.js.map +1 -1
  82. package/dist/examples/list-slot.d.ts +2 -0
  83. package/dist/examples/list-slot.d.ts.map +1 -0
  84. package/dist/examples/list-slot.js +14 -0
  85. package/dist/examples/list-slot.js.map +1 -0
  86. package/dist/examples/list-with-dropdown.js +2 -4
  87. package/dist/examples/list-with-dropdown.js.map +1 -1
  88. package/dist/examples/simple-heatmap.d.ts +2 -0
  89. package/dist/examples/simple-heatmap.d.ts.map +1 -0
  90. package/dist/examples/simple-heatmap.js +37 -0
  91. package/dist/examples/simple-heatmap.js.map +1 -0
  92. package/dist/examples/simple-progress-bar.d.ts +2 -0
  93. package/dist/examples/simple-progress-bar.d.ts.map +1 -0
  94. package/dist/examples/simple-progress-bar.js +36 -0
  95. package/dist/examples/simple-progress-bar.js.map +1 -0
  96. package/dist/index.d.ts +6 -0
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +6 -0
  99. package/dist/index.js.map +1 -1
  100. package/dist/internal/date-picker-widget.d.ts.map +1 -1
  101. package/dist/internal/date-picker-widget.js +5 -4
  102. package/dist/internal/date-picker-widget.js.map +1 -1
  103. package/dist/internal/navigation.d.ts.map +1 -1
  104. package/dist/internal/navigation.js +7 -2
  105. package/dist/internal/navigation.js.map +1 -1
  106. package/dist/internal/providers.d.ts.map +1 -1
  107. package/dist/internal/providers.js +42 -4
  108. package/dist/internal/providers.js.map +1 -1
  109. package/dist/logger.js +6 -1
  110. package/dist/logger.js.map +1 -1
  111. package/dist/state.d.ts +2 -0
  112. package/dist/state.d.ts.map +1 -1
  113. package/dist/state.js +31 -2
  114. package/dist/state.js.map +1 -1
  115. package/dist/theme.d.ts +1 -0
  116. package/dist/theme.d.ts.map +1 -1
  117. package/dist/theme.js +23 -1
  118. package/dist/theme.js.map +1 -1
  119. package/dist/utils.d.ts.map +1 -1
  120. package/dist/utils.js +6 -1
  121. package/dist/utils.js.map +1 -1
  122. package/package.json +3 -3
  123. package/src/apis/environment.tsx +6 -0
  124. package/src/app.tsx +1492 -0
  125. package/src/assets/default-app-icon.png +0 -0
  126. package/src/cli.tsx +105 -0
  127. package/src/compile.tsx +5 -2
  128. package/src/components/actions.tsx +9 -6
  129. package/src/components/detail.tsx +33 -23
  130. package/src/components/dropdown.tsx +3 -2
  131. package/src/components/footer.tsx +40 -7
  132. package/src/components/form/checkbox.tsx +2 -17
  133. package/src/components/form/date-picker.tsx +2 -2
  134. package/src/components/form/description.tsx +1 -1
  135. package/src/components/form/dropdown.tsx +22 -3
  136. package/src/components/form/file-picker.tsx +33 -10
  137. package/src/components/form/index.tsx +11 -7
  138. package/src/components/form/password-field.tsx +3 -3
  139. package/src/components/form/text-area.tsx +31 -6
  140. package/src/components/form/text-field.tsx +3 -3
  141. package/src/components/graph.tsx +21 -24
  142. package/src/components/heatmap.tsx +602 -0
  143. package/src/components/list.tsx +147 -78
  144. package/src/components/markdown.tsx +30 -0
  145. package/src/components/metadata.tsx +9 -2
  146. package/src/components/progress-bar.tsx +112 -0
  147. package/src/components/table.tsx +88 -71
  148. package/src/diagram-parser.tsx +17 -3
  149. package/src/examples/bar-graph-weekly.vitest.tsx +4 -4
  150. package/src/examples/detail-metadata-showcase.vitest.tsx +12 -12
  151. package/src/examples/form-basic.vitest.tsx +117 -16
  152. package/src/examples/graph-bar-chart.vitest.tsx +7 -7
  153. package/src/examples/graph-row.vitest.tsx +45 -45
  154. package/src/examples/graph-styles.vitest.tsx +19 -19
  155. package/src/examples/internal/descendants-rerender.vitest.tsx +94 -46
  156. package/src/examples/internal/simple-scrollbox.vitest.tsx +38 -14
  157. package/src/examples/list-dropdown-default.vitest.tsx +78 -58
  158. package/src/examples/list-slot.tsx +38 -0
  159. package/src/examples/list-with-detail.vitest.tsx +8 -8
  160. package/src/examples/list-with-dropdown.tsx +2 -2
  161. package/src/examples/list-with-dropdown.vitest.tsx +16 -16
  162. package/src/examples/list-with-sections.vitest.tsx +45 -32
  163. package/src/examples/simple-detail-table.vitest.tsx +2 -2
  164. package/src/examples/simple-file-picker.vitest.tsx +1 -1
  165. package/src/examples/simple-grid.vitest.tsx +27 -53
  166. package/src/examples/simple-heatmap.tsx +63 -0
  167. package/src/examples/simple-heatmap.vitest.tsx +88 -0
  168. package/src/examples/simple-progress-bar.tsx +82 -0
  169. package/src/examples/simple-progress-bar.vitest.tsx +72 -0
  170. package/src/examples/table-edge-cases.vitest.tsx +1 -1
  171. package/src/index.tsx +19 -0
  172. package/src/internal/date-picker-widget.tsx +23 -12
  173. package/src/internal/navigation.tsx +7 -2
  174. package/src/internal/providers.tsx +48 -3
  175. package/src/logger.tsx +6 -1
  176. package/src/state.tsx +38 -2
  177. package/src/theme.tsx +26 -2
  178. package/src/utils.tsx +6 -1
@@ -7,7 +7,7 @@ beforeEach(async () => {
7
7
  session = await launchTerminal({
8
8
  command: 'bun',
9
9
  args: ['src/examples/list-dropdown-default.tsx'],
10
- cols: 80,
10
+ cols: 100,
11
11
  rows: 30,
12
12
  })
13
13
  })
@@ -31,9 +31,9 @@ test('dropdown defaults to first item when no value is provided', async () => {
31
31
  "
32
32
 
33
33
 
34
- Dropdown Default Value Example ───────────────────────────────────────────
34
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
35
35
 
36
- > Search... Apple ▾
36
+ > Search... Apple ▾
37
37
 
38
38
  ›First Item This list has a dropdown
39
39
  Second Item The dropdown should default to first item
@@ -43,7 +43,7 @@ test('dropdown defaults to first item when no value is provided', async () => {
43
43
 
44
44
 
45
45
 
46
- ↵ show selected fruit ↑↓ navigate ^p dropdown powered by termcast.app
46
+ ↵ show selected fruit ↑↓ navigate ^k actions ^p filter by categorpowered by termcast.app
47
47
 
48
48
 
49
49
 
@@ -76,22 +76,22 @@ test('dropdown opens and shows items', async () => {
76
76
  "
77
77
 
78
78
 
79
- Dropdown Default Value Example ───────────────────────────────────────────
80
- ╭──────────────────────────────────────────────────────────────────────────╮
81
-
82
- │ Filter by category esc │
83
- │ │
84
- │ > Select category... │
85
- │ │
86
- │ ›Apple │
87
- │ Banana │
88
- │ Orange │
89
- │ Grape │
90
- │ │
91
- │ │
92
- │ ↵ select ↑↓ navigate powered by termcast.app │
93
- │ │
94
- ╰──────────────────────────────────────────────────────────────────────────╯
79
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
80
+ ╭──────────────────────────────────────────────────────────────────────────╮
81
+ > Search.│ Apple ▾
82
+ │ Filter by category esc │
83
+ ›First Ite│ │
84
+ Second It│ > Select category... │
85
+ Vegetable│ │
86
+ Carrot Wi│ ›Apple │
87
+ │ Banana │
88
+ │ Orange │
89
+ │ Grape │
90
+ │ │
91
+ ↵ show se│ │mcast.app
92
+ │ ↵ select ↑↓ navigate powered by termcast.app │
93
+ │ │
94
+ ╰──────────────────────────────────────────────────────────────────────────╯
95
95
 
96
96
 
97
97
 
@@ -113,22 +113,22 @@ test('dropdown opens and shows items', async () => {
113
113
  "
114
114
 
115
115
 
116
- Dropdown Default Value Example ───────────────────────────────────────────
117
- ╭──────────────────────────────────────────────────────────────────────────╮
118
-
119
- │ Filter by category esc │
120
- │ │
121
- │ > Select category... │
122
- │ │
123
- │ Apple │
124
- │ ›Banana │
125
- │ Orange │
126
- │ Grape │
127
- │ │
128
- │ │
129
- │ ↵ select ↑↓ navigate powered by termcast.app │
130
- │ │
131
- ╰──────────────────────────────────────────────────────────────────────────╯
116
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
117
+ ╭──────────────────────────────────────────────────────────────────────────╮
118
+ > Search.│ Apple ▾
119
+ │ Filter by category esc │
120
+ ›First Ite│ │
121
+ Second It│ > Select category... │
122
+ Vegetable│ │
123
+ Carrot Wi│ Apple │
124
+ │ ›Banana │
125
+ │ Orange │
126
+ │ Grape │
127
+ │ │
128
+ ↵ show se│ │mcast.app
129
+ │ ↵ select ↑↓ navigate powered by termcast.app │
130
+ │ │
131
+ ╰──────────────────────────────────────────────────────────────────────────╯
132
132
 
133
133
 
134
134
 
@@ -150,9 +150,9 @@ test('dropdown opens and shows items', async () => {
150
150
  "
151
151
 
152
152
 
153
- Dropdown Default Value Example ───────────────────────────────────────────
153
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
154
154
 
155
- > Search... Banana ▾
155
+ > Search... Banana ▾
156
156
 
157
157
  ›First Item This list has a dropdown
158
158
  Second Item The dropdown should default to first item
@@ -162,7 +162,7 @@ test('dropdown opens and shows items', async () => {
162
162
 
163
163
 
164
164
 
165
- ↵ show selected fruit ↑↓ navigate ^p dropdown powered by termcast.app
165
+ ↵ show selected fruit ↑↓ navigate ^k actions ^p filter by categorpowered by termcast.app
166
166
 
167
167
 
168
168
 
@@ -195,22 +195,22 @@ test('clicking dropdown opens it', async () => {
195
195
  "
196
196
 
197
197
 
198
- Dropdown Default Value Example ───────────────────────────────────────────
199
- ╭──────────────────────────────────────────────────────────────────────────╮
200
-
201
- │ Filter by category esc │
202
- │ │
203
- │ > Select category... │
204
- │ │
205
- │ ›Apple │
206
- │ Banana │
207
- │ Orange │
208
- │ Grape │
209
- │ │
210
- │ │
211
- │ ↵ select ↑↓ navigate powered by termcast.app │
212
- │ │
213
- ╰──────────────────────────────────────────────────────────────────────────╯
198
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
199
+ ╭──────────────────────────────────────────────────────────────────────────╮
200
+ > Search.│ Apple ▾
201
+ │ Filter by category esc │
202
+ ›First Ite│ │
203
+ Second It│ > Select category... │
204
+ Vegetable│ │
205
+ Carrot Wi│ ›Apple │
206
+ │ Banana │
207
+ │ Orange │
208
+ │ Grape │
209
+ │ │
210
+ ↵ show se│ │mcast.app
211
+ │ ↵ select ↑↓ navigate powered by termcast.app │
212
+ │ │
213
+ ╰──────────────────────────────────────────────────────────────────────────╯
214
214
 
215
215
 
216
216
 
@@ -232,9 +232,9 @@ test('clicking dropdown opens it', async () => {
232
232
  "
233
233
 
234
234
 
235
- Dropdown Default Value Example ───────────────────────────────────────────
235
+ Dropdown Default Value Example ───────────────────────────────────────────────────────────────
236
236
 
237
- > Search... Orange ▾
237
+ > Search... Orange ▾
238
238
 
239
239
  ›First Item This list has a dropdown
240
240
  Second Item The dropdown should default to first item
@@ -244,7 +244,7 @@ test('clicking dropdown opens it', async () => {
244
244
 
245
245
 
246
246
 
247
- ↵ show selected fruit ↑↓ navigate ^p dropdown powered by termcast.app
247
+ ↵ show selected fruit ↑↓ navigate ^k actions ^p filter by categorpowered by termcast.app
248
248
 
249
249
 
250
250
 
@@ -262,3 +262,23 @@ test('clicking dropdown opens it', async () => {
262
262
  "
263
263
  `)
264
264
  }, 10000)
265
+
266
+ test('clicking footer dropdown hint opens dropdown', async () => {
267
+ await session.text({
268
+ waitFor: (text) => {
269
+ return /Dropdown Default Value Example/i.test(text)
270
+ },
271
+ })
272
+
273
+ const beforeClick = await session.text()
274
+ expect(beforeClick).toContain('^p')
275
+
276
+ await session.click('^p', { first: true })
277
+
278
+ const afterClick = await session.text({
279
+ waitFor: (text) => {
280
+ return /Filter by category/i.test(text)
281
+ },
282
+ })
283
+ expect(afterClick).toContain('Filter by category')
284
+ }, 10000)
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Example: List with logo prop on the title bar, no dropdown.
3
+ * Logo appears on the right edge after the separator line.
4
+ */
5
+ import React from 'react'
6
+ import { List, ActionPanel, Action, renderWithProviders, Color } from 'termcast'
7
+
8
+ function ListSlotExample() {
9
+ const items = [
10
+ { id: '1', title: 'Dashboard', subtitle: 'Main overview' },
11
+ { id: '2', title: 'Settings', subtitle: 'Preferences' },
12
+ { id: '3', title: 'Profile', subtitle: 'Account info' },
13
+ { id: '4', title: 'Notifications', subtitle: 'Alerts' },
14
+ { id: '5', title: 'Analytics', subtitle: 'Usage stats' },
15
+ ]
16
+
17
+ return (
18
+ <List
19
+ logo={<text fg={Color.Orange}>◆ Acme</text>}
20
+ >
21
+ {items.map((item) => (
22
+ <List.Item
23
+ key={item.id}
24
+ id={item.id}
25
+ title={item.title}
26
+ subtitle={item.subtitle}
27
+ actions={
28
+ <ActionPanel>
29
+ <Action title="Open" onAction={() => {}} />
30
+ </ActionPanel>
31
+ }
32
+ />
33
+ ))}
34
+ </List>
35
+ )
36
+ }
37
+
38
+ renderWithProviders(<ListSlotExample />)
@@ -573,16 +573,16 @@ test('list with detail layout consistency - short vs long detail content', async
573
573
 
574
574
 
575
575
 
576
-
577
-
578
-
579
-
580
-
581
-
582
-
583
-
584
576
  ↑↓ navigate ^k actions │
585
577
 
578
+
579
+
580
+
581
+
582
+
583
+
584
+
585
+
586
586
  "
587
587
  `)
588
588
  expect(longDetailSnapshot).toMatchInlineSnapshot(`
@@ -1,5 +1,5 @@
1
1
  import React, { useState, ReactElement } from 'react'
2
- import { List, renderWithProviders } from 'termcast'
2
+ import { List, renderWithProviders, Color } from 'termcast'
3
3
  import type { DropdownProps } from 'termcast/src/components/list'
4
4
 
5
5
  function DrinkDropdown(props: {
@@ -73,7 +73,7 @@ function ListWithDropdownExample() {
73
73
  return (
74
74
  <List
75
75
  navigationTitle='Search Beers'
76
- // searchBarPlaceholder="Search your favorite drink"
76
+ logo={<text fg={Color.Orange}>◆ Acme</text>}
77
77
  searchBarAccessory={
78
78
  (
79
79
  <DrinkDropdown
@@ -33,7 +33,7 @@ test('list with dropdown navigation', async () => {
33
33
  "
34
34
 
35
35
 
36
- Search Beers ───────────────────────────────────────────────────
36
+ Search Beers ──────────────────────────────────────────── ◆ Acme
37
37
 
38
38
  > Search... All ▾
39
39
 
@@ -49,7 +49,7 @@ test('list with dropdown navigation', async () => {
49
49
  Apple Juice Juice
50
50
 
51
51
 
52
- ↑↓ navigate ^p dropdown ^k actions
52
+ ↑↓ navigate ^k actions ^p select drink type
53
53
 
54
54
 
55
55
 
@@ -69,7 +69,7 @@ test('list with dropdown navigation', async () => {
69
69
  "
70
70
 
71
71
 
72
- Search Beers ───────────────────────────────────────────────────
72
+ Search Beers ──────────────────────────────────────────── ◆ Acme
73
73
  ╭────────────────────────────────────────────────────────────────╮
74
74
  │ │
75
75
  │ Select Drink Type esc │
@@ -103,7 +103,7 @@ test('list with dropdown navigation', async () => {
103
103
  "
104
104
 
105
105
 
106
- Search Beers ───────────────────────────────────────────────────
106
+ Search Beers ──────────────────────────────────────────── ◆ Acme
107
107
  ╭────────────────────────────────────────────────────────────────╮
108
108
  │ │
109
109
  │ Select Drink Type esc │
@@ -135,7 +135,7 @@ test('list with dropdown navigation', async () => {
135
135
  "
136
136
 
137
137
 
138
- Search Beers ───────────────────────────────────────────────────
138
+ Search Beers ──────────────────────────────────────────── ◆ Acme
139
139
  ╭────────────────────────────────────────────────────────────────╮
140
140
  │ │
141
141
  │ Select Drink Type esc │
@@ -167,7 +167,7 @@ test('list with dropdown navigation', async () => {
167
167
  "
168
168
 
169
169
 
170
- Search Beers ───────────────────────────────────────────────────
170
+ Search Beers ──────────────────────────────────────────── ◆ Acme
171
171
  ╭────────────────────────────────────────────────────────────────╮
172
172
  │ │
173
173
  │ Select Drink Type esc │
@@ -203,7 +203,7 @@ test('list with dropdown navigation', async () => {
203
203
  "
204
204
 
205
205
 
206
- Search Beers ───────────────────────────────────────────────────
206
+ Search Beers ──────────────────────────────────────────── ◆ Acme
207
207
 
208
208
  > Search... Wine ▾
209
209
 
@@ -215,7 +215,7 @@ test('list with dropdown navigation', async () => {
215
215
 
216
216
 
217
217
 
218
- ↑↓ navigate ^p dropdown ^k actions
218
+ ↑↓ navigate ^k actions ^p select drink type
219
219
 
220
220
 
221
221
 
@@ -253,7 +253,7 @@ test('small screen: dropdown accessory wastes vertical space', async () => {
253
253
  "
254
254
 
255
255
 
256
- Search Beers ─────────────────────────────────────────
256
+ Search Beers ────────────────────────────────── ◆ Acme
257
257
 
258
258
  > Search... All ▾
259
259
 
@@ -265,7 +265,7 @@ test('small screen: dropdown accessory wastes vertical space', async () => {
265
265
  Pinot Noir Wine
266
266
 
267
267
 
268
- ↑↓ navigate ^p dropdown ^k actions"
268
+ ↑↓ navigate ^k actions ^p select drink type"
269
269
  `)
270
270
  } finally {
271
271
  smallSession.close()
@@ -292,7 +292,7 @@ test('list with dropdown search and filter', async () => {
292
292
  "
293
293
 
294
294
 
295
- Search Beers ───────────────────────────────────────────────────
295
+ Search Beers ──────────────────────────────────────────── ◆ Acme
296
296
  ╭────────────────────────────────────────────────────────────────╮
297
297
  │ │
298
298
  │ Select Drink Type esc │
@@ -334,7 +334,7 @@ test('list with dropdown search and filter', async () => {
334
334
  "
335
335
 
336
336
 
337
- Search Beers ───────────────────────────────────────────────────
337
+ Search Beers ──────────────────────────────────────────── ◆ Acme
338
338
 
339
339
  > Search... All ▾
340
340
 
@@ -370,7 +370,7 @@ test('list with dropdown search and filter', async () => {
370
370
  "
371
371
 
372
372
 
373
- Search Beers ───────────────────────────────────────────────────
373
+ Search Beers ──────────────────────────────────────────── ◆ Acme
374
374
 
375
375
  > Search... Wine ▾
376
376
 
@@ -382,7 +382,7 @@ test('list with dropdown search and filter', async () => {
382
382
 
383
383
 
384
384
 
385
- ↑↓ navigate ^p dropdown ^k actions
385
+ ↑↓ navigate ^k actions ^p select drink type
386
386
 
387
387
 
388
388
 
@@ -406,7 +406,7 @@ test('list with dropdown search and filter', async () => {
406
406
  "
407
407
 
408
408
 
409
- Search Beers ───────────────────────────────────────────────────
409
+ Search Beers ──────────────────────────────────────────── ◆ Acme
410
410
 
411
411
  > pinot Wine ▾
412
412
 
@@ -418,7 +418,7 @@ test('list with dropdown search and filter', async () => {
418
418
 
419
419
 
420
420
 
421
- ↑↓ navigate ^p dropdown ^k actions
421
+ ↑↓ navigate ^k actions ^p select drink type
422
422
 
423
423
 
424
424
 
@@ -334,67 +334,79 @@ test('list click functionality', async () => {
334
334
  },
335
335
  })
336
336
 
337
- // Click on "Banana" item (visible in initial view)
337
+ // Click on "Banana" should immediately execute first action (navigate to detail)
338
338
  await session.click('Banana', { first: true })
339
339
 
340
- const afterClickBananaSnapshot = await session.text()
341
- expect(afterClickBananaSnapshot).toMatchInlineSnapshot(`
340
+ const afterClickBanana = await session.text()
341
+ expect(afterClickBanana).toMatchInlineSnapshot(`
342
342
  "
343
343
 
344
344
 
345
- Simple List Example ────────────────────────────────────────────
346
345
 
347
- > Search items...
348
346
 
349
- Fruits
350
- Apple Red and sweet Fresh Popular
351
- ›Banana Yellow and nutritious Ripe
352
- Orange Citrus and juicy Fresh
353
- Grape Sweet clusters Seasonal
354
- Mango Tropical delight Imported
355
- Pineapple Sweet and tangy
356
- Strawberry Red and sweet Popular
347
+ Banana
357
348
 
349
+ A yellow tropical fruit that's nutritious and energy-rich.
358
350
 
351
+ Benefits
352
+
353
+ - High in potassium
354
+ - Natural energy booster
355
+ - Aids digestion
356
+
357
+
358
+
359
+ esc go back ^k actions
359
360
 
360
- ↵ view details ↑↓ navigate ^k actions
361
361
 
362
362
  "
363
363
  `)
364
+ expect(afterClickBanana).toContain('Banana')
365
+ expect(afterClickBanana).toContain('go back')
364
366
 
365
- // Click on "Apple" item
367
+ // Go back to list
368
+ await session.press('escape')
369
+ await session.text({ waitFor: (text) => /search/i.test(text) })
370
+
371
+ // Click on "Apple" — should also immediately execute (Apple has actions)
366
372
  await session.click('Apple', { first: true })
367
373
 
368
- const afterClickAppleSnapshot = await session.text()
369
- expect(afterClickAppleSnapshot).toMatchInlineSnapshot(`
374
+ const afterClickApple = await session.text()
375
+ expect(afterClickApple).toMatchInlineSnapshot(`
370
376
  "
371
377
 
372
378
 
373
- Simple List Example ────────────────────────────────────────────
374
379
 
375
- > Search items...
376
380
 
377
- Fruits
378
- ›Apple Red and sweet Fresh Popular
379
- Banana Yellow and nutritious Ripe
380
- Orange Citrus and juicy Fresh
381
- Grape Sweet clusters Seasonal
382
- Mango Tropical delight Imported
383
- Pineapple Sweet and tangy
384
- Strawberry Red and sweet Popular
381
+ Apple
385
382
 
383
+ A delicious red fruit that's sweet and crunchy.
386
384
 
385
+ Nutrition Facts
386
+
387
+ - High in fiber
388
+ - Rich in antioxidants
389
+ - Good source of vitamin C
390
+
391
+
392
+
393
+ esc go back ^k actions
387
394
 
388
- ↵ view details ↑↓ navigate ^k actions
389
395
 
390
396
  "
391
397
  `)
398
+ expect(afterClickApple).toContain('Apple')
399
+ expect(afterClickApple).toContain('go back')
400
+
401
+ // Go back to list
402
+ await session.press('escape')
403
+ await session.text({ waitFor: (text) => /search/i.test(text) })
392
404
 
393
- // Click on "Grape" item (visible in initial view)
405
+ // Click on "Grape" no actions, should just select
394
406
  await session.click('Grape', { first: true })
395
407
 
396
- const afterClickGrapeSnapshot = await session.text()
397
- expect(afterClickGrapeSnapshot).toMatchInlineSnapshot(`
408
+ const afterClickGrape = await session.text()
409
+ expect(afterClickGrape).toMatchInlineSnapshot(`
398
410
  "
399
411
 
400
412
 
@@ -417,7 +429,8 @@ test('list click functionality', async () => {
417
429
 
418
430
  "
419
431
  `)
420
- }, 10000)
432
+ expect(afterClickGrape).toContain('Grape')
433
+ }, 15000)
421
434
 
422
435
  test('list actions panel with ctrl+k', async () => {
423
436
  await session.text({
@@ -66,7 +66,6 @@ test('markdown tables render with borderless layout', async () => {
66
66
  ap-south-1 89ms /api/health 500
67
67
 
68
68
 
69
- esc go back ^k actions powered by termcast.app
70
69
 
71
70
 
72
71
 
@@ -83,6 +82,7 @@ test('markdown tables render with borderless layout', async () => {
83
82
 
84
83
 
85
84
 
85
+ esc go back ^k actions powered by termcast.app
86
86
 
87
87
  "
88
88
  `)
@@ -166,7 +166,6 @@ test('two tables render side by side in a Row', async () => {
166
166
  ap-south-1 89ms /api/health 500
167
167
 
168
168
 
169
- esc go back ^k actions powered by termcast.app
170
169
 
171
170
 
172
171
 
@@ -183,6 +182,7 @@ test('two tables render side by side in a Row', async () => {
183
182
 
184
183
 
185
184
 
185
+ esc go back ^k actions powered by termcast.app
186
186
 
187
187
  "
188
188
  `)
@@ -271,7 +271,7 @@ test('selecting first item with enter adds it to the list', async () => {
271
271
  │ Enter file path...
272
272
 
273
273
  │ Selected files:
274
- │ • /Users/morse/Documents/GitHub/termcast/termcast/src
274
+ │ • /Users/morse/Documents/GitHub/termcast/termcast/src
275
275
  │ Choose a folder for output
276
276
 
277
277
  ◇ Select Single File