termcast 1.3.48 → 1.3.50

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 (255) hide show
  1. package/dist/build.d.ts.map +1 -1
  2. package/dist/build.js +12 -0
  3. package/dist/build.js.map +1 -1
  4. package/dist/cli.js +5 -40
  5. package/dist/cli.js.map +1 -1
  6. package/dist/colors.d.ts +7 -7
  7. package/dist/colors.js +7 -7
  8. package/dist/compile.d.ts +6 -1
  9. package/dist/compile.d.ts.map +1 -1
  10. package/dist/compile.js +45 -26
  11. package/dist/compile.js.map +1 -1
  12. package/dist/components/actions.js +1 -1
  13. package/dist/components/actions.js.map +1 -1
  14. package/dist/components/bar-chart.d.ts +38 -0
  15. package/dist/components/bar-chart.d.ts.map +1 -0
  16. package/dist/components/bar-chart.js +158 -0
  17. package/dist/components/bar-chart.js.map +1 -0
  18. package/dist/components/bar-graph.d.ts +41 -0
  19. package/dist/components/bar-graph.d.ts.map +1 -0
  20. package/dist/components/bar-graph.js +95 -0
  21. package/dist/components/bar-graph.js.map +1 -0
  22. package/dist/components/detail.d.ts.map +1 -1
  23. package/dist/components/detail.js +5 -7
  24. package/dist/components/detail.js.map +1 -1
  25. package/dist/components/footer.d.ts.map +1 -1
  26. package/dist/components/footer.js +8 -9
  27. package/dist/components/footer.js.map +1 -1
  28. package/dist/components/form/date-picker.d.ts.map +1 -1
  29. package/dist/components/form/date-picker.js +7 -1
  30. package/dist/components/form/date-picker.js.map +1 -1
  31. package/dist/components/form/dropdown.d.ts.map +1 -1
  32. package/dist/components/form/dropdown.js +10 -2
  33. package/dist/components/form/dropdown.js.map +1 -1
  34. package/dist/components/form/index.d.ts.map +1 -1
  35. package/dist/components/form/index.js +4 -5
  36. package/dist/components/form/index.js.map +1 -1
  37. package/dist/components/form/use-form-navigation.d.ts.map +1 -1
  38. package/dist/components/form/use-form-navigation.js +6 -0
  39. package/dist/components/form/use-form-navigation.js.map +1 -1
  40. package/dist/components/graph.d.ts +111 -0
  41. package/dist/components/graph.d.ts.map +1 -0
  42. package/dist/components/graph.js +392 -0
  43. package/dist/components/graph.js.map +1 -0
  44. package/dist/components/icon.js +5 -5
  45. package/dist/components/icon.js.map +1 -1
  46. package/dist/components/list.d.ts +53 -5
  47. package/dist/components/list.d.ts.map +1 -1
  48. package/dist/components/list.js +125 -71
  49. package/dist/components/list.js.map +1 -1
  50. package/dist/components/loading-bar.js +3 -3
  51. package/dist/components/loading-bar.js.map +1 -1
  52. package/dist/components/loading-text.d.ts +1 -1
  53. package/dist/components/loading-text.d.ts.map +1 -1
  54. package/dist/components/loading-text.js +3 -1
  55. package/dist/components/loading-text.js.map +1 -1
  56. package/dist/components/metadata.js +2 -2
  57. package/dist/components/metadata.js.map +1 -1
  58. package/dist/components/row.d.ts +10 -0
  59. package/dist/components/row.d.ts.map +1 -0
  60. package/dist/components/row.js +12 -0
  61. package/dist/components/row.js.map +1 -0
  62. package/dist/components/table.d.ts +57 -0
  63. package/dist/components/table.d.ts.map +1 -0
  64. package/dist/components/table.js +365 -0
  65. package/dist/components/table.js.map +1 -0
  66. package/dist/descendants.js +13 -13
  67. package/dist/descendants.js.map +1 -1
  68. package/dist/examples/bar-graph-weekly.d.ts +2 -0
  69. package/dist/examples/bar-graph-weekly.d.ts.map +1 -0
  70. package/dist/examples/bar-graph-weekly.js +95 -0
  71. package/dist/examples/bar-graph-weekly.js.map +1 -0
  72. package/dist/examples/components-weird-places.d.ts +2 -0
  73. package/dist/examples/components-weird-places.d.ts.map +1 -0
  74. package/dist/examples/components-weird-places.js +46 -0
  75. package/dist/examples/components-weird-places.js.map +1 -0
  76. package/dist/examples/graph-bar-chart.d.ts +2 -0
  77. package/dist/examples/graph-bar-chart.d.ts.map +1 -0
  78. package/dist/examples/graph-bar-chart.js +270 -0
  79. package/dist/examples/graph-bar-chart.js.map +1 -0
  80. package/dist/examples/graph-multi-series.d.ts +2 -0
  81. package/dist/examples/graph-multi-series.d.ts.map +1 -0
  82. package/dist/examples/graph-multi-series.js +23 -0
  83. package/dist/examples/graph-multi-series.js.map +1 -0
  84. package/dist/examples/graph-polymarket.d.ts +2 -0
  85. package/dist/examples/graph-polymarket.d.ts.map +1 -0
  86. package/dist/examples/graph-polymarket.js +109 -0
  87. package/dist/examples/graph-polymarket.js.map +1 -0
  88. package/dist/examples/graph-row.d.ts +2 -0
  89. package/dist/examples/graph-row.d.ts.map +1 -0
  90. package/dist/examples/graph-row.js +226 -0
  91. package/dist/examples/graph-row.js.map +1 -0
  92. package/dist/examples/graph-styles.d.ts +2 -0
  93. package/dist/examples/graph-styles.d.ts.map +1 -0
  94. package/dist/examples/graph-styles.js +316 -0
  95. package/dist/examples/graph-styles.js.map +1 -0
  96. package/dist/examples/list-accessory-table.d.ts +2 -0
  97. package/dist/examples/list-accessory-table.d.ts.map +1 -0
  98. package/dist/examples/list-accessory-table.js +46 -0
  99. package/dist/examples/list-accessory-table.js.map +1 -0
  100. package/dist/examples/list-item-accessories.d.ts +2 -0
  101. package/dist/examples/list-item-accessories.d.ts.map +1 -0
  102. package/dist/examples/list-item-accessories.js +27 -0
  103. package/dist/examples/list-item-accessories.js.map +1 -0
  104. package/dist/examples/list-no-actions.d.ts +2 -0
  105. package/dist/examples/list-no-actions.d.ts.map +1 -0
  106. package/dist/examples/list-no-actions.js +7 -0
  107. package/dist/examples/list-no-actions.js.map +1 -0
  108. package/dist/examples/simple-detail-table.d.ts +2 -0
  109. package/dist/examples/simple-detail-table.d.ts.map +1 -0
  110. package/dist/examples/simple-detail-table.js +45 -0
  111. package/dist/examples/simple-detail-table.js.map +1 -0
  112. package/dist/examples/simple-graph.d.ts +2 -0
  113. package/dist/examples/simple-graph.d.ts.map +1 -0
  114. package/dist/examples/simple-graph.js +32 -0
  115. package/dist/examples/simple-graph.js.map +1 -0
  116. package/dist/examples/simple-table-wrap.d.ts +2 -0
  117. package/dist/examples/simple-table-wrap.d.ts.map +1 -0
  118. package/dist/examples/simple-table-wrap.js +37 -0
  119. package/dist/examples/simple-table-wrap.js.map +1 -0
  120. package/dist/examples/table-edge-cases.d.ts +2 -0
  121. package/dist/examples/table-edge-cases.d.ts.map +1 -0
  122. package/dist/examples/table-edge-cases.js +70 -0
  123. package/dist/examples/table-edge-cases.js.map +1 -0
  124. package/dist/examples/table-flex-grow.d.ts +2 -0
  125. package/dist/examples/table-flex-grow.d.ts.map +1 -0
  126. package/dist/examples/table-flex-grow.js +18 -0
  127. package/dist/examples/table-flex-grow.js.map +1 -0
  128. package/dist/extensions/dev.d.ts.map +1 -1
  129. package/dist/extensions/dev.js +5 -1
  130. package/dist/extensions/dev.js.map +1 -1
  131. package/dist/globals.d.ts +1 -0
  132. package/dist/globals.d.ts.map +1 -1
  133. package/dist/globals.js +2 -0
  134. package/dist/globals.js.map +1 -1
  135. package/dist/index.d.ts +10 -0
  136. package/dist/index.d.ts.map +1 -1
  137. package/dist/index.js +10 -0
  138. package/dist/index.js.map +1 -1
  139. package/dist/internal/date-picker-widget.d.ts.map +1 -1
  140. package/dist/internal/date-picker-widget.js +4 -0
  141. package/dist/internal/date-picker-widget.js.map +1 -1
  142. package/dist/internal/providers.d.ts.map +1 -1
  143. package/dist/internal/providers.js +1 -3
  144. package/dist/internal/providers.js.map +1 -1
  145. package/dist/markdown-utils.d.ts +22 -1
  146. package/dist/markdown-utils.d.ts.map +1 -1
  147. package/dist/markdown-utils.js +66 -1
  148. package/dist/markdown-utils.js.map +1 -1
  149. package/dist/opentui.d.ts +4 -0
  150. package/dist/opentui.d.ts.map +1 -0
  151. package/dist/opentui.js +3 -0
  152. package/dist/opentui.js.map +1 -0
  153. package/dist/release.d.ts +2 -1
  154. package/dist/release.d.ts.map +1 -1
  155. package/dist/release.js +2 -1
  156. package/dist/release.js.map +1 -1
  157. package/dist/state.d.ts +1 -0
  158. package/dist/state.d.ts.map +1 -1
  159. package/dist/state.js +1 -1
  160. package/dist/state.js.map +1 -1
  161. package/dist/theme.d.ts +1 -0
  162. package/dist/theme.d.ts.map +1 -1
  163. package/dist/theme.js +13 -0
  164. package/dist/theme.js.map +1 -1
  165. package/dist/themes/nerv.json +227 -0
  166. package/dist/themes/termcast.json +72 -71
  167. package/dist/themes.d.ts +2 -1
  168. package/dist/themes.d.ts.map +1 -1
  169. package/dist/themes.js +7 -5
  170. package/dist/themes.js.map +1 -1
  171. package/dist/utils.d.ts.map +1 -1
  172. package/dist/utils.js +3 -0
  173. package/dist/utils.js.map +1 -1
  174. package/package.json +13 -5
  175. package/src/build.tsx +13 -0
  176. package/src/cli.tsx +5 -49
  177. package/src/colors.tsx +7 -7
  178. package/src/compile.tsx +52 -29
  179. package/src/components/actions.tsx +1 -1
  180. package/src/components/bar-chart.tsx +271 -0
  181. package/src/components/bar-graph.tsx +214 -0
  182. package/src/components/detail.tsx +7 -8
  183. package/src/components/footer.tsx +14 -15
  184. package/src/components/form/date-picker.tsx +9 -0
  185. package/src/components/form/dropdown.tsx +13 -3
  186. package/src/components/form/index.tsx +4 -6
  187. package/src/components/form/use-form-navigation.tsx +6 -0
  188. package/src/components/graph.tsx +506 -0
  189. package/src/components/icon.tsx +5 -5
  190. package/src/components/list.tsx +210 -102
  191. package/src/components/loading-bar.tsx +3 -3
  192. package/src/components/loading-text.tsx +4 -2
  193. package/src/components/metadata.tsx +2 -2
  194. package/src/components/row.tsx +31 -0
  195. package/src/components/table.tsx +511 -0
  196. package/src/descendants.tsx +13 -13
  197. package/src/examples/action-shortcut.vitest.tsx +1 -1
  198. package/src/examples/actions-context.vitest.tsx +1 -1
  199. package/src/examples/bar-graph-weekly.tsx +264 -0
  200. package/src/examples/bar-graph-weekly.vitest.tsx +275 -0
  201. package/src/examples/detail-metadata-showcase.vitest.tsx +8 -8
  202. package/src/examples/form-basic.vitest.tsx +239 -0
  203. package/src/examples/form-dropdown.vitest.tsx +29 -29
  204. package/src/examples/form-tagpicker.vitest.tsx +27 -27
  205. package/src/examples/github.vitest.tsx +4 -4
  206. package/src/examples/graph-bar-chart.tsx +408 -0
  207. package/src/examples/graph-bar-chart.vitest.tsx +283 -0
  208. package/src/examples/graph-multi-series.tsx +36 -0
  209. package/src/examples/graph-multi-series.vitest.tsx +89 -0
  210. package/src/examples/graph-polymarket.tsx +182 -0
  211. package/src/examples/graph-polymarket.vitest.tsx +130 -0
  212. package/src/examples/graph-row.tsx +347 -0
  213. package/src/examples/graph-row.vitest.tsx +295 -0
  214. package/src/examples/graph-styles.tsx +457 -0
  215. package/src/examples/graph-styles.vitest.tsx +322 -0
  216. package/src/examples/list-accessory-table.tsx +77 -0
  217. package/src/examples/list-detail-metadata.vitest.tsx +21 -21
  218. package/src/examples/list-dropdown-default.vitest.tsx +12 -12
  219. package/src/examples/list-item-accessories.tsx +106 -0
  220. package/src/examples/list-item-accessories.vitest.tsx +115 -0
  221. package/src/examples/list-no-actions.tsx +18 -0
  222. package/src/examples/list-no-actions.vitest.tsx +97 -0
  223. package/src/examples/list-spacing-mode.vitest.tsx +6 -6
  224. package/src/examples/list-with-detail.vitest.tsx +92 -92
  225. package/src/examples/list-with-dropdown.vitest.tsx +49 -6
  226. package/src/examples/list-with-sections.vitest.tsx +61 -56
  227. package/src/examples/simple-detail-markdown.vitest.tsx +21 -17
  228. package/src/examples/simple-detail-table.tsx +65 -0
  229. package/src/examples/simple-detail-table.vitest.tsx +200 -0
  230. package/src/examples/simple-graph.tsx +51 -0
  231. package/src/examples/simple-graph.vitest.tsx +124 -0
  232. package/src/examples/simple-grid.vitest.tsx +3 -3
  233. package/src/examples/simple-list-search.vitest.tsx +65 -0
  234. package/src/examples/simple-navigation.vitest.tsx +3 -3
  235. package/src/examples/simple-table-wrap.tsx +55 -0
  236. package/src/examples/simple-table-wrap.vitest.tsx +91 -0
  237. package/src/examples/store.vitest.tsx +1 -1
  238. package/src/examples/table-edge-cases.tsx +72 -0
  239. package/src/examples/table-edge-cases.vitest.tsx +307 -0
  240. package/src/examples/table-flex-grow.tsx +53 -0
  241. package/src/examples/table-flex-grow.vitest.tsx +124 -0
  242. package/src/extensions/dev.tsx +7 -1
  243. package/src/globals.ts +3 -0
  244. package/src/index.tsx +31 -0
  245. package/src/internal/date-picker-widget.tsx +4 -0
  246. package/src/internal/providers.tsx +1 -4
  247. package/src/markdown-utils.tsx +82 -1
  248. package/src/opentui.tsx +5 -0
  249. package/src/release.tsx +3 -0
  250. package/src/state.tsx +2 -1
  251. package/src/theme.tsx +14 -0
  252. package/src/themes/nerv.json +231 -0
  253. package/src/themes/termcast.json +75 -71
  254. package/src/themes.ts +8 -5
  255. package/src/utils.tsx +4 -0
@@ -0,0 +1,264 @@
1
+ // Example: BarGraph vertical stacked bar chart in a List with side detail.
2
+ // Shows weekly data with default palette colors. Enter pushes to full Detail.
3
+
4
+ import React from 'react'
5
+ import { List, Detail, BarGraph, Row, Action, ActionPanel } from 'termcast'
6
+ import { useNavigation } from 'termcast/src/internal/navigation'
7
+ import { renderWithProviders } from '../utils'
8
+
9
+ // ── Data ─────────────────────────────────────────────────────────────
10
+
11
+ const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
12
+
13
+ interface DataSet {
14
+ title: string
15
+ subtitle: string
16
+ series: Array<{ data: number[]; title: string }>
17
+ }
18
+
19
+ const dataSets: DataSet[] = [
20
+ {
21
+ title: 'Weekly Traffic',
22
+ subtitle: '3 channels across 6 days',
23
+ series: [
24
+ { data: [40, 30, 25, 15, 50, 40], title: 'Direct' },
25
+ { data: [30, 35, 15, 20, 35, 30], title: 'Organic' },
26
+ { data: [20, 25, 10, 10, 25, 20], title: 'Referral' },
27
+ ],
28
+ },
29
+ {
30
+ title: 'Revenue by Region',
31
+ subtitle: 'EMEA / APAC / Americas',
32
+ series: [
33
+ { data: [60, 45, 30, 55, 70, 50], title: 'Americas' },
34
+ { data: [25, 30, 20, 35, 25, 30], title: 'EMEA' },
35
+ { data: [15, 20, 10, 10, 20, 15], title: 'APAC' },
36
+ ],
37
+ },
38
+ {
39
+ title: 'Server Load',
40
+ subtitle: 'CPU / Memory / IO',
41
+ series: [
42
+ { data: [45, 55, 35, 70, 60, 40], title: 'CPU' },
43
+ { data: [30, 25, 40, 20, 35, 30], title: 'Memory' },
44
+ ],
45
+ },
46
+ ]
47
+
48
+ // Second week data for side-by-side comparison
49
+ const week2Series = [
50
+ { data: [50, 40, 30, 25, 60, 45], title: 'Direct' },
51
+ { data: [35, 30, 20, 25, 40, 35], title: 'Organic' },
52
+ { data: [25, 20, 15, 15, 30, 25], title: 'Referral' },
53
+ ]
54
+
55
+ // Stress test: many columns (20 bars)
56
+ const manyColsLabels = Array.from({ length: 20 }, (_, i) => `D${i + 1}`)
57
+ const manyColsSeries = [
58
+ { data: Array.from({ length: 20 }, () => 20 + Math.floor(Math.random() * 60)), title: 'A' },
59
+ { data: Array.from({ length: 20 }, () => 10 + Math.floor(Math.random() * 40)), title: 'B' },
60
+ ]
61
+
62
+ // Stress test: long labels
63
+ const longLabels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday & Sunday']
64
+ const longLabelsSeries = [
65
+ { data: [40, 30, 25, 15, 50, 40], title: 'Views' },
66
+ { data: [20, 25, 10, 10, 25, 20], title: 'Clicks' },
67
+ ]
68
+
69
+ // Stress test: many series (8 series)
70
+ const manySeriesData: Array<{ data: number[]; title: string }> = Array.from(
71
+ { length: 8 },
72
+ (_, i) => ({
73
+ data: [10 + i * 5, 15 + i * 3, 8 + i * 4, 12 + i * 2, 20 + i * 6, 5 + i * 7],
74
+ title: `Series ${i + 1}`,
75
+ }),
76
+ )
77
+
78
+ // ── Full Detail view (pushed on Enter) ───────────────────────────────
79
+
80
+ function BarGraphDetailView({ item }: { item: DataSet }): any {
81
+ const { pop } = useNavigation()
82
+
83
+ return (
84
+ <Detail
85
+ navigationTitle={item.title}
86
+ markdown={[
87
+ `# ${item.title}`,
88
+ '',
89
+ item.subtitle,
90
+ ].join('\n')}
91
+ metadata={
92
+ <Detail.Metadata>
93
+ <BarGraph height={15} labels={days}>
94
+ {item.series.map((s, i) => {
95
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
96
+ })}
97
+ </BarGraph>
98
+ </Detail.Metadata>
99
+ }
100
+ actions={
101
+ <ActionPanel>
102
+ <Action title="Go Back" onAction={() => { pop() }} />
103
+ </ActionPanel>
104
+ }
105
+ />
106
+ )
107
+ }
108
+
109
+ // ── Main list ────────────────────────────────────────────────────────
110
+
111
+ function BarGraphWeeklyExample() {
112
+ const { push, pop } = useNavigation()
113
+
114
+ return (
115
+ <List navigationTitle="BarGraph Showcase" isShowingDetail={true}>
116
+ {dataSets.map((item) => {
117
+ return (
118
+ <List.Item
119
+ key={item.title}
120
+ title={item.title}
121
+ subtitle={item.subtitle}
122
+ detail={
123
+ <List.Item.Detail
124
+ metadata={
125
+ <List.Item.Detail.Metadata>
126
+ <BarGraph height={10} labels={days}>
127
+ {item.series.map((s, i) => {
128
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
129
+ })}
130
+ </BarGraph>
131
+ </List.Item.Detail.Metadata>
132
+ }
133
+ />
134
+ }
135
+ actions={
136
+ <ActionPanel>
137
+ <Action
138
+ title="Open Detail"
139
+ onAction={() => { push(<BarGraphDetailView item={item} />) }}
140
+ />
141
+ </ActionPanel>
142
+ }
143
+ />
144
+ )
145
+ })}
146
+ <List.Item
147
+ key="many-columns"
148
+ title="Many Columns (20)"
149
+ subtitle="Overflow test with 20 bars"
150
+ detail={
151
+ <List.Item.Detail
152
+ metadata={
153
+ <List.Item.Detail.Metadata>
154
+ <BarGraph height={10} labels={manyColsLabels}>
155
+ {manyColsSeries.map((s, i) => {
156
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
157
+ })}
158
+ </BarGraph>
159
+ </List.Item.Detail.Metadata>
160
+ }
161
+ />
162
+ }
163
+ />
164
+ <List.Item
165
+ key="many-series"
166
+ title="Many Series (8)"
167
+ subtitle="Legend overflow test"
168
+ detail={
169
+ <List.Item.Detail
170
+ metadata={
171
+ <List.Item.Detail.Metadata>
172
+ <BarGraph height={10} labels={days}>
173
+ {manySeriesData.map((s, i) => {
174
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
175
+ })}
176
+ </BarGraph>
177
+ </List.Item.Detail.Metadata>
178
+ }
179
+ />
180
+ }
181
+ />
182
+ <List.Item
183
+ key="long-labels"
184
+ title="Long Labels"
185
+ subtitle="Labels wider than bar columns"
186
+ detail={
187
+ <List.Item.Detail
188
+ metadata={
189
+ <List.Item.Detail.Metadata>
190
+ <BarGraph height={10} labels={longLabels}>
191
+ {longLabelsSeries.map((s, i) => {
192
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
193
+ })}
194
+ </BarGraph>
195
+ </List.Item.Detail.Metadata>
196
+ }
197
+ />
198
+ }
199
+ />
200
+ <List.Item
201
+ key="side-by-side"
202
+ title="Week 1 vs Week 2"
203
+ subtitle="Two graphs in a Row"
204
+ detail={
205
+ <List.Item.Detail
206
+ metadata={
207
+ <List.Item.Detail.Metadata>
208
+ <Row>
209
+ <BarGraph height={10} labels={days}>
210
+ {dataSets[0]!.series.map((s, i) => {
211
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
212
+ })}
213
+ </BarGraph>
214
+ <BarGraph height={10} labels={days}>
215
+ {week2Series.map((s, i) => {
216
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
217
+ })}
218
+ </BarGraph>
219
+ </Row>
220
+ </List.Item.Detail.Metadata>
221
+ }
222
+ />
223
+ }
224
+ actions={
225
+ <ActionPanel>
226
+ <Action
227
+ title="Open Detail"
228
+ onAction={() => {
229
+ push(
230
+ <Detail
231
+ navigationTitle="Week 1 vs Week 2"
232
+ metadata={
233
+ <Detail.Metadata>
234
+ <Row>
235
+ <BarGraph height={15} labels={days}>
236
+ {dataSets[0]!.series.map((s, i) => {
237
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
238
+ })}
239
+ </BarGraph>
240
+ <BarGraph height={15} labels={days}>
241
+ {week2Series.map((s, i) => {
242
+ return <BarGraph.Series key={i} data={s.data} title={s.title} />
243
+ })}
244
+ </BarGraph>
245
+ </Row>
246
+ </Detail.Metadata>
247
+ }
248
+ actions={
249
+ <ActionPanel>
250
+ <Action title="Go Back" onAction={() => { pop() }} />
251
+ </ActionPanel>
252
+ }
253
+ />
254
+ )
255
+ }}
256
+ />
257
+ </ActionPanel>
258
+ }
259
+ />
260
+ </List>
261
+ )
262
+ }
263
+
264
+ renderWithProviders(<BarGraphWeeklyExample />)
@@ -0,0 +1,275 @@
1
+ // E2E tests for BarGraph vertical stacked bar chart.
2
+ // Bar segments are filled with █ chars so they show in text snapshots.
3
+
4
+ import { test, expect, afterEach, beforeEach } from 'vitest'
5
+ import { launchTerminal, Session } from 'tuistory/src'
6
+
7
+ let session: Session
8
+
9
+ beforeEach(async () => {
10
+ session = await launchTerminal({
11
+ command: 'bun',
12
+ args: ['src/examples/bar-graph-weekly.tsx'],
13
+ cols: 80,
14
+ rows: 30,
15
+ })
16
+ })
17
+
18
+ afterEach(() => {
19
+ session?.close()
20
+ })
21
+
22
+ test('bar graph renders bars, labels, and legend', async () => {
23
+ const text = await session.text({
24
+ waitFor: (text) => {
25
+ return text.includes('Mon') && text.includes('Sat') && text.includes('Direct')
26
+ },
27
+ timeout: 10000,
28
+ })
29
+
30
+ expect(text).toMatchInlineSnapshot(`
31
+ "
32
+
33
+
34
+ BarGraph Showcase ────────────────────────────────────────────────────────
35
+
36
+ > Search...
37
+
38
+ ›Weekly Traffic 3 channels across 6 d │ ███
39
+ Revenue by Region EMEA / APAC / Amer │ ███ ███ ███ ███
40
+ Server Load CPU / Memory / IO │ ███ ███ ███ ███
41
+ Many Columns (20) Overflow test with │ ███ ███ ███ ███ ███
42
+ Many Series (8) Legend overflow test │ ███ ███ ███ ███ ███ ███
43
+ Long Labels Labels wider than bar co │ ███ ███ ███ ███ ███ ███
44
+ Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ ███ ███
45
+ │ ███ ███ ███ ███ ███ ███
46
+ │ ███ ███ ███ ███ ███ ███
47
+ │ Mon Tue Wed Thu Fri Sat
48
+ ↵ open detail ↑↓ navigate ^k act │ ■ Direct ■ Organic ■ Referral
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ "
62
+ `)
63
+
64
+ expect(text).toContain('Mon')
65
+ expect(text).toContain('Sat')
66
+ expect(text).toContain('Direct')
67
+ expect(text).toContain('█')
68
+ }, 30000)
69
+
70
+ test('many columns (20) clips with overflow hidden', async () => {
71
+ await session.text({ waitFor: (t) => t.includes('Many Columns'), timeout: 10000 })
72
+ // Navigate: Weekly Traffic, Revenue, Server Load, Many Columns = 3 downs
73
+ session.sendKey('down')
74
+ session.sendKey('down')
75
+ session.sendKey('down')
76
+
77
+ const text = await session.text({
78
+ waitFor: (t) => t.includes('›Many Columns'),
79
+ timeout: 10000,
80
+ })
81
+
82
+ expect(text).toMatchInlineSnapshot(`
83
+ "
84
+
85
+
86
+ BarGraph Showcase ────────────────────────────────────────────────────────
87
+
88
+ > Search...
89
+
90
+ Weekly Traffic 3 channels across 6 d │ ███ ███ ███
91
+ Revenue by Region EMEA / APAC / Amer │ ███ ███ ███ ███
92
+ Server Load CPU / Memory / IO │ ███ ███ ███ ███ ███ ███
93
+ ›Many Columns (20) Overflow test with │ ███ ███ ███ ███ ███ ███ ███ ███ ██
94
+ Many Series (8) Legend overflow test │ ███ ███ ███ ███ ███ ███ ███ ███ ██
95
+ Long Labels Labels wider than bar co │ ███ ███ ███ ███ ███ ███ ███ ███ ██
96
+ Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ ███ ███ ███ ███ ██
97
+ │ ███ ███ ███ ███ ███ ███ ███ ███ ██
98
+ │ ███ ███ ███ ███ ███ ███ ███ ███ ██
99
+ │ D1 D2 D3 D4 D5 D6 D7 D8 D9
100
+ ↑↓ navigate ^k actions │ ■ A ■ B
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+ "
114
+ `)
115
+
116
+ // Some labels visible, overflow clips the rest
117
+ expect(text).toContain('D1')
118
+ expect(text).toContain('█')
119
+ }, 30000)
120
+
121
+ test('many series (8) legend clips on one line', async () => {
122
+ await session.text({ waitFor: (t) => t.includes('Many Series'), timeout: 10000 })
123
+ // Navigate: Weekly, Revenue, Server, Many Columns, Many Series = 4 downs
124
+ session.sendKey('down')
125
+ session.sendKey('down')
126
+ session.sendKey('down')
127
+ session.sendKey('down')
128
+
129
+ const text = await session.text({
130
+ waitFor: (t) => t.includes('›Many Series'),
131
+ timeout: 10000,
132
+ })
133
+
134
+ expect(text).toMatchInlineSnapshot(`
135
+ "
136
+
137
+
138
+ BarGraph Showcase ────────────────────────────────────────────────────────
139
+
140
+ > Search...
141
+
142
+ Weekly Traffic 3 channels across 6 d │ ███ ███ ███ ███ ███
143
+ Revenue by Region EMEA / APAC / Amer │ ███ ███ ███ ███ ███ ███
144
+ Server Load CPU / Memory / IO │ ███ ███ ███ ███ ███ ███
145
+ Many Columns (20) Overflow test with │ ███ ███ ███ ███ ███ ███
146
+ ›Many Series (8) Legend overflow test │ ███ ███ ███ ███ ███ ███
147
+ Long Labels Labels wider than bar co │ ███ ███ ███ ███ ███ ███
148
+ Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ ███ ███
149
+ │ ███ ███ ███ ███ ███ ███
150
+ │ ███ ███ ███ ███ ███ ███
151
+ │ Mon Tue Wed Thu Fri Sat
152
+ ↑↓ navigate ^k actions │ ■ Series 1 ■ Series 2 ■ Series 3 ■
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+ "
166
+ `)
167
+
168
+ // First series visible in legend
169
+ expect(text).toContain('Series 1')
170
+ expect(text).toContain('█')
171
+ }, 30000)
172
+
173
+ test('long labels truncated by overflow hidden', async () => {
174
+ await session.text({ waitFor: (t) => t.includes('Long Labels'), timeout: 10000 })
175
+ // Navigate: Weekly, Revenue, Server, Many Columns, Many Series, Long Labels = 5 downs
176
+ session.sendKey('down')
177
+ session.sendKey('down')
178
+ session.sendKey('down')
179
+ session.sendKey('down')
180
+ session.sendKey('down')
181
+
182
+ const text = await session.text({
183
+ waitFor: (t) => t.includes('›Long Labels'),
184
+ timeout: 10000,
185
+ })
186
+
187
+ expect(text).toMatchInlineSnapshot(`
188
+ "
189
+
190
+
191
+ BarGraph Showcase ────────────────────────────────────────────────────────
192
+
193
+ > Search...
194
+
195
+ Weekly Traffic 3 channels across 6 d │ ███
196
+ Revenue by Region EMEA / APAC / Amer │ ███ ███ ███
197
+ Server Load CPU / Memory / IO │ ███ ███ ███ ███
198
+ Many Columns (20) Overflow test with │ ███ ███ ███ ███
199
+ Many Series (8) Legend overflow test │ ███ ███ ███ ███ ███
200
+ ›Long Labels Labels wider than bar co │ ███ ███ ███ ███ ███ ███
201
+ Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ ███ ███
202
+ │ ███ ███ ███ ███ ███ ███
203
+ │ ███ ███ ███ ███ ███ ███
204
+ │ Mon Tue Wed Thu Fri Sat
205
+ ↑↓ navigate ^k actions │ ■ Views ■ Clicks
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+ "
219
+ `)
220
+
221
+ expect(text).toContain('Long Labels')
222
+ expect(text).toContain('█')
223
+ }, 30000)
224
+
225
+ test('side-by-side bar graphs in a Row', async () => {
226
+ await session.text({ waitFor: (t) => t.includes('Week 1'), timeout: 10000 })
227
+ // Navigate: Weekly, Revenue, Server, Many Columns, Many Series, Long Labels, Side-by-side = 6 downs
228
+ session.sendKey('down')
229
+ session.sendKey('down')
230
+ session.sendKey('down')
231
+ session.sendKey('down')
232
+ session.sendKey('down')
233
+ session.sendKey('down')
234
+
235
+ const text = await session.text({
236
+ waitFor: (t) => t.includes('›Week 1 vs Week 2'),
237
+ timeout: 10000,
238
+ })
239
+
240
+ expect(text).toMatchInlineSnapshot(`
241
+ "
242
+
243
+
244
+ BarGraph Showcase ────────────────────────────────────────────────────────
245
+
246
+ > Search...
247
+
248
+ Weekly Traffic 3 channels across 6 d │ █
249
+ Revenue by Region EMEA / APAC / Amer │ ███ ███ █ ███
250
+ Server Load CPU / Memory / IO │ ███ ███ █ ███ ███
251
+ Many Columns (20) Overflow test with │ ███ ███ ███ █ ███ ███ ███ ███
252
+ Many Series (8) Legend overflow test │ ███ ███ ███ ███ █ ███ ███ ███ ███
253
+ Long Labels Labels wider than bar co │ ███ ███ ███ ███ █ ███ ███ ███ ███
254
+ ›Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ █ ███ ███ ███ ███
255
+ │ ███ ███ ███ ███ █ ███ ███ ███ ███
256
+ │ ███ ███ ███ ███ █ ███ ███ ███ ███
257
+ │ Mon Tue Wed Thu F Mon Tue Wed Thu
258
+ ↵ open detail ↑↓ navigate ^k act │ ■ Direct ■ Organi ■ Direct ■ Organ
259
+
260
+
261
+
262
+
263
+
264
+
265
+
266
+
267
+
268
+
269
+
270
+
271
+ "
272
+ `)
273
+
274
+ expect(text).toContain('Mon')
275
+ }, 30000)
@@ -91,7 +91,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
91
91
 
92
92
  Team: Platform
93
93
 
94
- ─────────────────────────────────────────────────────────────────────────────────────────────
94
+ ────────────────────────────────────────────────────────────────────────────────────────────
95
95
 
96
96
  Status: Active
97
97
 
@@ -101,7 +101,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
101
101
 
102
102
  Risk: Medium
103
103
 
104
- ─────────────────────────────────────────────────────────────────────────────────────────────
104
+ ────────────────────────────────────────────────────────────────────────────────────────────
105
105
 
106
106
  Description: This is a comprehensive metadata showcase that demonstrates all the different
107
107
  ways you can display information using the Detail.Metadata component.
@@ -112,7 +112,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
112
112
 
113
113
  Reviewer: Bob Smith
114
114
 
115
- ─────────────────────────────────────────────────────────────────────────────────────────────
115
+ ────────────────────────────────────────────────────────────────────────────────────────────
116
116
 
117
117
  Repository: github.com/example
118
118
 
@@ -120,7 +120,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
120
120
 
121
121
  PR Link: github.com/organization/repository/pull/12345
122
122
 
123
- ─────────────────────────────────────────────────────────────────────────────────────────────
123
+ ────────────────────────────────────────────────────────────────────────────────────────────
124
124
 
125
125
  Labels: documentation enhancement good first issue
126
126
 
@@ -134,7 +134,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
134
134
 
135
135
  Due Date: 2024-02-01
136
136
 
137
- ─────────────────────────────────────────────────────────────────────────────────────────────
137
+ ────────────────────────────────────────────────────────────────────────────────────────────
138
138
 
139
139
  Metrics
140
140
 
@@ -148,7 +148,6 @@ test('detail metadata showcase renders markdown and metadata together', async ()
148
148
 
149
149
 
150
150
 
151
- esc go back powered by termcast
152
151
 
153
152
 
154
153
 
@@ -160,6 +159,7 @@ test('detail metadata showcase renders markdown and metadata together', async ()
160
159
 
161
160
 
162
161
 
162
+ esc go back ^k actions powered by termcast.app
163
163
 
164
164
  "
165
165
  `)
@@ -318,8 +318,8 @@ test('detail metadata renders long values in column layout', async () => {
318
318
  Watchers: @alice @bob @charlie
319
319
 
320
320
 
321
+ esc go back ^k actions powered by termcast.app
321
322
 
322
- esc go back powered by termcast
323
323
 
324
324
 
325
325
 
@@ -511,7 +511,7 @@ test('detail metadata renders tag lists with multiple items', async () => {
511
511
 
512
512
 
513
513
 
514
- esc go back powered by termcast
514
+ esc go back ^k actions powered by termcast.app
515
515
 
516
516
  "
517
517
  `)