termcast 1.3.47 → 1.3.49

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 (278) hide show
  1. package/dist/apis/cache.d.ts.map +1 -1
  2. package/dist/apis/cache.js +1 -2
  3. package/dist/apis/cache.js.map +1 -1
  4. package/dist/apis/localstorage.d.ts.map +1 -1
  5. package/dist/apis/localstorage.js +1 -2
  6. package/dist/apis/localstorage.js.map +1 -1
  7. package/dist/apis/sqlite.d.ts +7 -0
  8. package/dist/apis/sqlite.d.ts.map +1 -0
  9. package/dist/apis/sqlite.js +13 -0
  10. package/dist/apis/sqlite.js.map +1 -0
  11. package/dist/build.d.ts.map +1 -1
  12. package/dist/build.js +14 -5
  13. package/dist/build.js.map +1 -1
  14. package/dist/cli.js +5 -40
  15. package/dist/cli.js.map +1 -1
  16. package/dist/colors.d.ts +7 -7
  17. package/dist/colors.js +7 -7
  18. package/dist/compile.d.ts +6 -1
  19. package/dist/compile.d.ts.map +1 -1
  20. package/dist/compile.js +46 -27
  21. package/dist/compile.js.map +1 -1
  22. package/dist/components/actions.js +1 -1
  23. package/dist/components/actions.js.map +1 -1
  24. package/dist/components/bar-chart.d.ts +38 -0
  25. package/dist/components/bar-chart.d.ts.map +1 -0
  26. package/dist/components/bar-chart.js +158 -0
  27. package/dist/components/bar-chart.js.map +1 -0
  28. package/dist/components/bar-graph.d.ts +41 -0
  29. package/dist/components/bar-graph.d.ts.map +1 -0
  30. package/dist/components/bar-graph.js +95 -0
  31. package/dist/components/bar-graph.js.map +1 -0
  32. package/dist/components/detail.d.ts.map +1 -1
  33. package/dist/components/detail.js +5 -7
  34. package/dist/components/detail.js.map +1 -1
  35. package/dist/components/footer.d.ts.map +1 -1
  36. package/dist/components/footer.js +8 -9
  37. package/dist/components/footer.js.map +1 -1
  38. package/dist/components/form/date-picker.d.ts.map +1 -1
  39. package/dist/components/form/date-picker.js +7 -1
  40. package/dist/components/form/date-picker.js.map +1 -1
  41. package/dist/components/form/dropdown.d.ts.map +1 -1
  42. package/dist/components/form/dropdown.js +10 -2
  43. package/dist/components/form/dropdown.js.map +1 -1
  44. package/dist/components/form/index.d.ts.map +1 -1
  45. package/dist/components/form/index.js +4 -5
  46. package/dist/components/form/index.js.map +1 -1
  47. package/dist/components/form/use-form-navigation.d.ts.map +1 -1
  48. package/dist/components/form/use-form-navigation.js +6 -0
  49. package/dist/components/form/use-form-navigation.js.map +1 -1
  50. package/dist/components/graph.d.ts +111 -0
  51. package/dist/components/graph.d.ts.map +1 -0
  52. package/dist/components/graph.js +392 -0
  53. package/dist/components/graph.js.map +1 -0
  54. package/dist/components/icon.js +5 -5
  55. package/dist/components/icon.js.map +1 -1
  56. package/dist/components/list.d.ts +53 -5
  57. package/dist/components/list.d.ts.map +1 -1
  58. package/dist/components/list.js +125 -71
  59. package/dist/components/list.js.map +1 -1
  60. package/dist/components/loading-bar.js +3 -3
  61. package/dist/components/loading-bar.js.map +1 -1
  62. package/dist/components/loading-text.d.ts +1 -1
  63. package/dist/components/loading-text.d.ts.map +1 -1
  64. package/dist/components/loading-text.js +3 -1
  65. package/dist/components/loading-text.js.map +1 -1
  66. package/dist/components/metadata.js +2 -2
  67. package/dist/components/metadata.js.map +1 -1
  68. package/dist/components/row.d.ts +10 -0
  69. package/dist/components/row.d.ts.map +1 -0
  70. package/dist/components/row.js +12 -0
  71. package/dist/components/row.js.map +1 -0
  72. package/dist/components/table.d.ts +57 -0
  73. package/dist/components/table.d.ts.map +1 -0
  74. package/dist/components/table.js +365 -0
  75. package/dist/components/table.js.map +1 -0
  76. package/dist/descendants.js +13 -13
  77. package/dist/descendants.js.map +1 -1
  78. package/dist/examples/bar-graph-weekly.d.ts +2 -0
  79. package/dist/examples/bar-graph-weekly.d.ts.map +1 -0
  80. package/dist/examples/bar-graph-weekly.js +95 -0
  81. package/dist/examples/bar-graph-weekly.js.map +1 -0
  82. package/dist/examples/components-weird-places.d.ts +2 -0
  83. package/dist/examples/components-weird-places.d.ts.map +1 -0
  84. package/dist/examples/components-weird-places.js +46 -0
  85. package/dist/examples/components-weird-places.js.map +1 -0
  86. package/dist/examples/graph-bar-chart.d.ts +2 -0
  87. package/dist/examples/graph-bar-chart.d.ts.map +1 -0
  88. package/dist/examples/graph-bar-chart.js +270 -0
  89. package/dist/examples/graph-bar-chart.js.map +1 -0
  90. package/dist/examples/graph-multi-series.d.ts +2 -0
  91. package/dist/examples/graph-multi-series.d.ts.map +1 -0
  92. package/dist/examples/graph-multi-series.js +23 -0
  93. package/dist/examples/graph-multi-series.js.map +1 -0
  94. package/dist/examples/graph-polymarket.d.ts +2 -0
  95. package/dist/examples/graph-polymarket.d.ts.map +1 -0
  96. package/dist/examples/graph-polymarket.js +109 -0
  97. package/dist/examples/graph-polymarket.js.map +1 -0
  98. package/dist/examples/graph-row.d.ts +2 -0
  99. package/dist/examples/graph-row.d.ts.map +1 -0
  100. package/dist/examples/graph-row.js +226 -0
  101. package/dist/examples/graph-row.js.map +1 -0
  102. package/dist/examples/graph-styles.d.ts +2 -0
  103. package/dist/examples/graph-styles.d.ts.map +1 -0
  104. package/dist/examples/graph-styles.js +316 -0
  105. package/dist/examples/graph-styles.js.map +1 -0
  106. package/dist/examples/list-accessory-table.d.ts +2 -0
  107. package/dist/examples/list-accessory-table.d.ts.map +1 -0
  108. package/dist/examples/list-accessory-table.js +46 -0
  109. package/dist/examples/list-accessory-table.js.map +1 -0
  110. package/dist/examples/list-item-accessories.d.ts +2 -0
  111. package/dist/examples/list-item-accessories.d.ts.map +1 -0
  112. package/dist/examples/list-item-accessories.js +27 -0
  113. package/dist/examples/list-item-accessories.js.map +1 -0
  114. package/dist/examples/list-no-actions.d.ts +2 -0
  115. package/dist/examples/list-no-actions.d.ts.map +1 -0
  116. package/dist/examples/list-no-actions.js +7 -0
  117. package/dist/examples/list-no-actions.js.map +1 -0
  118. package/dist/examples/simple-detail-table.d.ts +2 -0
  119. package/dist/examples/simple-detail-table.d.ts.map +1 -0
  120. package/dist/examples/simple-detail-table.js +45 -0
  121. package/dist/examples/simple-detail-table.js.map +1 -0
  122. package/dist/examples/simple-graph.d.ts +2 -0
  123. package/dist/examples/simple-graph.d.ts.map +1 -0
  124. package/dist/examples/simple-graph.js +32 -0
  125. package/dist/examples/simple-graph.js.map +1 -0
  126. package/dist/examples/simple-table-wrap.d.ts +2 -0
  127. package/dist/examples/simple-table-wrap.d.ts.map +1 -0
  128. package/dist/examples/simple-table-wrap.js +37 -0
  129. package/dist/examples/simple-table-wrap.js.map +1 -0
  130. package/dist/examples/table-edge-cases.d.ts +2 -0
  131. package/dist/examples/table-edge-cases.d.ts.map +1 -0
  132. package/dist/examples/table-edge-cases.js +70 -0
  133. package/dist/examples/table-edge-cases.js.map +1 -0
  134. package/dist/examples/table-flex-grow.d.ts +2 -0
  135. package/dist/examples/table-flex-grow.d.ts.map +1 -0
  136. package/dist/examples/table-flex-grow.js +18 -0
  137. package/dist/examples/table-flex-grow.js.map +1 -0
  138. package/dist/extensions/dev.d.ts.map +1 -1
  139. package/dist/extensions/dev.js +5 -1
  140. package/dist/extensions/dev.js.map +1 -1
  141. package/dist/globals.d.ts +1 -0
  142. package/dist/globals.d.ts.map +1 -1
  143. package/dist/globals.js +2 -0
  144. package/dist/globals.js.map +1 -1
  145. package/dist/index.d.ts +10 -0
  146. package/dist/index.d.ts.map +1 -1
  147. package/dist/index.js +10 -0
  148. package/dist/index.js.map +1 -1
  149. package/dist/internal/date-picker-widget.d.ts.map +1 -1
  150. package/dist/internal/date-picker-widget.js +4 -0
  151. package/dist/internal/date-picker-widget.js.map +1 -1
  152. package/dist/internal/providers.d.ts.map +1 -1
  153. package/dist/internal/providers.js +1 -3
  154. package/dist/internal/providers.js.map +1 -1
  155. package/dist/logger.d.ts.map +1 -1
  156. package/dist/logger.js +2 -1
  157. package/dist/logger.js.map +1 -1
  158. package/dist/markdown-utils.d.ts +22 -1
  159. package/dist/markdown-utils.d.ts.map +1 -1
  160. package/dist/markdown-utils.js +66 -1
  161. package/dist/markdown-utils.js.map +1 -1
  162. package/dist/opentui.d.ts +4 -0
  163. package/dist/opentui.d.ts.map +1 -0
  164. package/dist/opentui.js +3 -0
  165. package/dist/opentui.js.map +1 -0
  166. package/dist/release.d.ts +2 -1
  167. package/dist/release.d.ts.map +1 -1
  168. package/dist/release.js +2 -1
  169. package/dist/release.js.map +1 -1
  170. package/dist/state.d.ts +1 -0
  171. package/dist/state.d.ts.map +1 -1
  172. package/dist/state.js +1 -1
  173. package/dist/state.js.map +1 -1
  174. package/dist/swift-runtime.d.ts.map +1 -1
  175. package/dist/swift-runtime.js +20 -5
  176. package/dist/swift-runtime.js.map +1 -1
  177. package/dist/theme.d.ts +1 -0
  178. package/dist/theme.d.ts.map +1 -1
  179. package/dist/theme.js +13 -0
  180. package/dist/theme.js.map +1 -1
  181. package/dist/themes/nerv.json +227 -0
  182. package/dist/themes/termcast.json +72 -71
  183. package/dist/themes.d.ts +2 -1
  184. package/dist/themes.d.ts.map +1 -1
  185. package/dist/themes.js +7 -5
  186. package/dist/themes.js.map +1 -1
  187. package/dist/utils.d.ts.map +1 -1
  188. package/dist/utils.js +4 -1
  189. package/dist/utils.js.map +1 -1
  190. package/package.json +12 -4
  191. package/src/apis/cache.test.ts +1 -1
  192. package/src/apis/cache.tsx +1 -2
  193. package/src/apis/localstorage.tsx +1 -2
  194. package/src/apis/sqlite.ts +14 -0
  195. package/src/build.tsx +15 -5
  196. package/src/cli.tsx +5 -49
  197. package/src/colors.tsx +7 -7
  198. package/src/compile.tsx +53 -30
  199. package/src/components/actions.tsx +1 -1
  200. package/src/components/bar-chart.tsx +271 -0
  201. package/src/components/bar-graph.tsx +214 -0
  202. package/src/components/detail.tsx +7 -8
  203. package/src/components/footer.tsx +14 -15
  204. package/src/components/form/date-picker.tsx +9 -0
  205. package/src/components/form/dropdown.tsx +13 -3
  206. package/src/components/form/index.tsx +4 -6
  207. package/src/components/form/use-form-navigation.tsx +6 -0
  208. package/src/components/graph.tsx +506 -0
  209. package/src/components/icon.tsx +5 -5
  210. package/src/components/list.tsx +210 -102
  211. package/src/components/loading-bar.tsx +3 -3
  212. package/src/components/loading-text.tsx +4 -2
  213. package/src/components/metadata.tsx +2 -2
  214. package/src/components/row.tsx +31 -0
  215. package/src/components/table.tsx +511 -0
  216. package/src/descendants.tsx +13 -13
  217. package/src/examples/action-shortcut.vitest.tsx +1 -1
  218. package/src/examples/actions-context.vitest.tsx +1 -1
  219. package/src/examples/bar-graph-weekly.tsx +264 -0
  220. package/src/examples/bar-graph-weekly.vitest.tsx +275 -0
  221. package/src/examples/detail-metadata-showcase.vitest.tsx +22 -22
  222. package/src/examples/form-basic.vitest.tsx +239 -0
  223. package/src/examples/form-dropdown.vitest.tsx +29 -29
  224. package/src/examples/form-tagpicker.vitest.tsx +27 -27
  225. package/src/examples/github.vitest.tsx +4 -4
  226. package/src/examples/graph-bar-chart.tsx +408 -0
  227. package/src/examples/graph-bar-chart.vitest.tsx +283 -0
  228. package/src/examples/graph-multi-series.tsx +36 -0
  229. package/src/examples/graph-multi-series.vitest.tsx +89 -0
  230. package/src/examples/graph-polymarket.tsx +182 -0
  231. package/src/examples/graph-polymarket.vitest.tsx +130 -0
  232. package/src/examples/graph-row.tsx +347 -0
  233. package/src/examples/graph-row.vitest.tsx +295 -0
  234. package/src/examples/graph-styles.tsx +457 -0
  235. package/src/examples/graph-styles.vitest.tsx +322 -0
  236. package/src/examples/list-accessory-table.tsx +77 -0
  237. package/src/examples/list-detail-metadata.vitest.tsx +21 -21
  238. package/src/examples/list-dropdown-default.vitest.tsx +12 -12
  239. package/src/examples/list-item-accessories.tsx +106 -0
  240. package/src/examples/list-item-accessories.vitest.tsx +115 -0
  241. package/src/examples/list-no-actions.tsx +18 -0
  242. package/src/examples/list-no-actions.vitest.tsx +97 -0
  243. package/src/examples/list-spacing-mode.vitest.tsx +6 -6
  244. package/src/examples/list-with-detail.vitest.tsx +73 -73
  245. package/src/examples/list-with-dropdown.vitest.tsx +49 -6
  246. package/src/examples/list-with-sections.vitest.tsx +61 -56
  247. package/src/examples/simple-detail-markdown.vitest.tsx +21 -18
  248. package/src/examples/simple-detail-table.tsx +65 -0
  249. package/src/examples/simple-detail-table.vitest.tsx +200 -0
  250. package/src/examples/simple-graph.tsx +51 -0
  251. package/src/examples/simple-graph.vitest.tsx +124 -0
  252. package/src/examples/simple-grid.vitest.tsx +3 -3
  253. package/src/examples/simple-list-search.vitest.tsx +65 -0
  254. package/src/examples/simple-navigation.vitest.tsx +3 -3
  255. package/src/examples/simple-table-wrap.tsx +55 -0
  256. package/src/examples/simple-table-wrap.vitest.tsx +91 -0
  257. package/src/examples/store.vitest.tsx +1 -1
  258. package/src/examples/table-edge-cases.tsx +72 -0
  259. package/src/examples/table-edge-cases.vitest.tsx +307 -0
  260. package/src/examples/table-flex-grow.tsx +53 -0
  261. package/src/examples/table-flex-grow.vitest.tsx +124 -0
  262. package/src/extensions/dev.tsx +7 -1
  263. package/src/globals.ts +3 -0
  264. package/src/index.tsx +31 -0
  265. package/src/internal/date-picker-widget.tsx +4 -0
  266. package/src/internal/providers.tsx +1 -4
  267. package/src/logger.tsx +2 -1
  268. package/src/markdown-utils.tsx +82 -1
  269. package/src/opentui.tsx +5 -0
  270. package/src/release.tsx +3 -0
  271. package/src/state.tsx +2 -1
  272. package/src/swift-runtime.tsx +19 -5
  273. package/src/theme.tsx +14 -0
  274. package/src/themes/nerv.json +231 -0
  275. package/src/themes/termcast.json +75 -71
  276. package/src/themes.ts +8 -5
  277. package/src/utils.test.tsx +1 -1
  278. package/src/utils.tsx +5 -1
@@ -97,7 +97,7 @@ test.skipIf(!extensionExists)('github extension shows command list on launch', a
97
97
 
98
98
 
99
99
 
100
- ↵ run command ↑↓ navigate ^k actions powered by termcast
100
+ ↵ run command ↑↓ navigate ^k actions powered by termcast.app
101
101
 
102
102
 
103
103
 
@@ -146,7 +146,7 @@ test.skipIf(!extensionExists)('github extension can navigate commands', async ()
146
146
 
147
147
 
148
148
 
149
- ↵ run command ↑↓ navigate ^k actions powered by termcast
149
+ ↵ run command ↑↓ navigate ^k actions powered by termcast.app
150
150
 
151
151
 
152
152
 
@@ -192,7 +192,7 @@ test.skipIf(!extensionExists)('github extension can open actions panel', async (
192
192
  │ Settings │
193
193
  │ Configure GitHub... ⌃⇧, │
194
194
  │ Change Theme... │
195
- See Console Logs
195
+ Toggle Console Logs
196
196
  │ │
197
197
  │ │
198
198
  │ │
@@ -239,7 +239,7 @@ test.skipIf(!extensionExists)('github extension can search commands', async () =
239
239
 
240
240
 
241
241
 
242
- ↵ run command ↑↓ navigate ^k actions powered by termcast
242
+ ↵ run command ↑↓ navigate ^k actions powered by termcast.app
243
243
 
244
244
 
245
245
 
@@ -0,0 +1,408 @@
1
+ // Example: BarChart component showcase with horizontal stacked bars.
2
+ // Demonstrates budget breakdowns, disk usage, portfolios, and stress tests
3
+ // with many segments. Shows BarChart in list detail metadata and full Detail view.
4
+
5
+ import React from 'react'
6
+ import { List, Detail, BarChart, Graph, Color, Action, ActionPanel } from 'termcast'
7
+ import { useNavigation } from 'termcast/src/internal/navigation'
8
+ import { renderWithProviders } from '../utils'
9
+
10
+ // ── Item definitions ─────────────────────────────────────────────────
11
+
12
+ interface BarItem {
13
+ title: string
14
+ subtitle: string
15
+ segments: Array<{ value: number; label?: string; color?: Color.ColorLike }>
16
+ markdown?: string
17
+ meta: Array<{ title: string; text: string; color?: Color.ColorLike }>
18
+ /** Optional line chart data shown alongside the bar */
19
+ lineData?: { data: number[]; xLabels: string[] }
20
+ }
21
+
22
+ const items: BarItem[] = [
23
+ // ── Budget breakdown (3 segments) ──────────────────────────
24
+ {
25
+ title: 'Monthly Budget',
26
+ subtitle: 'Spent / Remaining / Savings',
27
+ segments: [
28
+ { value: 4850, label: 'Spent' },
29
+ { value: 707, label: 'Remaining' },
30
+ { value: 617, label: 'Savings' },
31
+ ],
32
+ markdown: [
33
+ '## Monthly Budget',
34
+ '',
35
+ 'Budget allocation for the current month.',
36
+ '',
37
+ '- **Spent**: $4,850 (78.6%)',
38
+ '- **Remaining**: $707 (11.5%)',
39
+ '- **Savings**: $617 (10.0%)',
40
+ ].join('\n'),
41
+ meta: [
42
+ { title: 'Total', text: '$6,174' },
43
+ { title: 'Spent', text: '78.6%', color: Color.Red },
44
+ { title: 'Saved', text: '10.0%', color: Color.Green },
45
+ ],
46
+ },
47
+
48
+ // ── Disk usage (4 segments) ────────────────────────────────
49
+ {
50
+ title: 'Disk Usage',
51
+ subtitle: 'System / Apps / Media / Free',
52
+ segments: [
53
+ { value: 120, label: 'System' },
54
+ { value: 85, label: 'Apps' },
55
+ { value: 210, label: 'Media' },
56
+ { value: 85, label: 'Free' },
57
+ ],
58
+ meta: [
59
+ { title: 'Total', text: '500 GB' },
60
+ { title: 'Used', text: '415 GB (83%)', color: Color.Orange },
61
+ { title: 'Free', text: '85 GB (17%)', color: Color.Green },
62
+ ],
63
+ },
64
+
65
+ // ── Portfolio (5 segments) ─────────────────────────────────
66
+ {
67
+ title: 'Investment Portfolio',
68
+ subtitle: 'Stocks / Bonds / Cash / Crypto / Real Estate',
69
+ segments: [
70
+ { value: 45000, label: 'Stocks' },
71
+ { value: 20000, label: 'Bonds' },
72
+ { value: 10000, label: 'Cash' },
73
+ { value: 8000, label: 'Crypto' },
74
+ { value: 17000, label: 'Real Estate' },
75
+ ],
76
+ markdown: [
77
+ '## Portfolio Allocation',
78
+ '',
79
+ 'Diversified across 5 asset classes.',
80
+ '',
81
+ '| Asset | Value | % |',
82
+ '|-------|-------|---|',
83
+ '| Stocks | $45k | 45% |',
84
+ '| Bonds | $20k | 20% |',
85
+ '| Real Estate | $17k | 17% |',
86
+ '| Cash | $10k | 10% |',
87
+ '| Crypto | $8k | 8% |',
88
+ ].join('\n'),
89
+ meta: [
90
+ { title: 'Total', text: '$100,000' },
91
+ { title: 'Risk', text: 'Moderate', color: Color.Yellow },
92
+ ],
93
+ },
94
+
95
+ // ── CPU breakdown (4 segments) ─────────────────────────────
96
+ {
97
+ title: 'CPU Time',
98
+ subtitle: 'User / System / IO Wait / Idle',
99
+ segments: [
100
+ { value: 42, label: 'User' },
101
+ { value: 18, label: 'System' },
102
+ { value: 5, label: 'IO Wait' },
103
+ { value: 35, label: 'Idle' },
104
+ ],
105
+ lineData: {
106
+ data: [25, 30, 45, 60, 55, 72, 80, 65, 50, 40, 35, 55, 70, 85, 90, 75, 60, 45, 38, 30],
107
+ xLabels: ['0h', '6h', '12h', '18h', '24h'],
108
+ },
109
+ meta: [
110
+ { title: 'User', text: '42%', color: Color.Blue },
111
+ { title: 'System', text: '18%', color: Color.Orange },
112
+ { title: 'Idle', text: '35%', color: Color.Green },
113
+ ],
114
+ },
115
+
116
+ // ── Revenue split (6 segments) ─────────────────────────────
117
+ {
118
+ title: 'Revenue by Product',
119
+ subtitle: '6 product lines',
120
+ segments: [
121
+ { value: 380, label: 'Enterprise' },
122
+ { value: 240, label: 'Pro' },
123
+ { value: 150, label: 'Starter' },
124
+ { value: 90, label: 'API' },
125
+ { value: 60, label: 'Add-ons' },
126
+ { value: 30, label: 'Support' },
127
+ ],
128
+ meta: [
129
+ { title: 'Total ARR', text: '$950K' },
130
+ { title: 'Top product', text: 'Enterprise (40%)', color: Color.Green },
131
+ ],
132
+ },
133
+
134
+ // ── Two even (50/50) ───────────────────────────────────────
135
+ {
136
+ title: 'A/B Test Split',
137
+ subtitle: 'Control vs Variant (50/50)',
138
+ segments: [
139
+ { value: 50, label: 'Control' },
140
+ { value: 50, label: 'Variant' },
141
+ ],
142
+ meta: [
143
+ { title: 'Control', text: '50%' },
144
+ { title: 'Variant', text: '50%' },
145
+ { title: 'p-value', text: '0.043', color: Color.Green },
146
+ ],
147
+ },
148
+
149
+ // ── Single segment (100%) ──────────────────────────────────
150
+ {
151
+ title: 'Storage Full',
152
+ subtitle: '100% used',
153
+ segments: [
154
+ { value: 100, label: 'Used' },
155
+ ],
156
+ meta: [
157
+ { title: 'Status', text: 'FULL', color: Color.Red },
158
+ { title: 'Action', text: 'Delete files!' },
159
+ ],
160
+ },
161
+
162
+ // ── Dominant + tiny segments ───────────────────────────────
163
+ {
164
+ title: 'Market Share',
165
+ subtitle: 'One dominant + many tiny players',
166
+ segments: [
167
+ { value: 85, label: 'Leader' },
168
+ { value: 5, label: 'Runner-up' },
169
+ { value: 3, label: 'Third' },
170
+ { value: 2, label: 'Fourth' },
171
+ { value: 1.5, label: 'Fifth' },
172
+ { value: 1, label: 'Sixth' },
173
+ { value: 0.8 },
174
+ { value: 0.5 },
175
+ { value: 0.4 },
176
+ { value: 0.3 },
177
+ { value: 0.2 },
178
+ { value: 0.1 },
179
+ { value: 0.1 },
180
+ { value: 0.1 },
181
+ ],
182
+ markdown: [
183
+ '## Market Concentration',
184
+ '',
185
+ 'Highly concentrated market with one dominant player at **85%**.',
186
+ 'Many tiny segments should be hidden or collapsed.',
187
+ '',
188
+ 'Tests behavior with 14 segments where most are < 1%.',
189
+ ].join('\n'),
190
+ meta: [
191
+ { title: 'HHI', text: '7,264 (monopoly)', color: Color.Red },
192
+ { title: 'Segments', text: '14 total' },
193
+ { title: 'Visible', text: 'Tiny ones hidden' },
194
+ ],
195
+ },
196
+
197
+ // ── Many equal segments ────────────────────────────────────
198
+ {
199
+ title: 'Equal Distribution',
200
+ subtitle: '10 equal segments',
201
+ segments: Array.from({ length: 10 }, (_, i) => ({
202
+ value: 10,
203
+ label: `Slice ${i + 1}`,
204
+ })),
205
+ meta: [
206
+ { title: 'Segments', text: '10' },
207
+ { title: 'Each', text: '10%' },
208
+ ],
209
+ },
210
+
211
+ // ── Custom colors ──────────────────────────────────────────
212
+ {
213
+ title: 'Custom Colors',
214
+ subtitle: 'Explicit color per segment',
215
+ segments: [
216
+ { value: 40, label: 'Red', color: Color.Red },
217
+ { value: 30, label: 'Green', color: Color.Green },
218
+ { value: 20, label: 'Blue', color: Color.Blue },
219
+ { value: 10, label: 'Yellow', color: Color.Yellow },
220
+ ],
221
+ meta: [
222
+ { title: 'Mode', text: 'Manual colors' },
223
+ { title: 'Override', text: 'Per-segment color prop' },
224
+ ],
225
+ },
226
+
227
+ // ── Needs/Wants budget ─────────────────────────────────────
228
+ {
229
+ title: 'Needs vs Wants',
230
+ subtitle: '50/30/20 budget rule',
231
+ segments: [
232
+ { value: 2826, label: 'Needs' },
233
+ { value: 2023, label: 'Wants' },
234
+ { value: 617, label: 'Savings' },
235
+ ],
236
+ lineData: {
237
+ data: [150, 155, 148, 162, 158, 165, 170, 168, 175, 180, 178, 185, 190, 188, 195, 192, 198, 202, 200, 208],
238
+ xLabels: ['W1', 'W2', 'W3', 'W4'],
239
+ },
240
+ meta: [
241
+ { title: 'Needs', text: '51.7%', color: Color.Orange },
242
+ { title: 'Wants', text: '37.0%', color: Color.Blue },
243
+ { title: 'Savings', text: '11.3%', color: Color.Green },
244
+ ],
245
+ },
246
+
247
+ // ── Stress test: 20 segments ───────────────────────────────
248
+ {
249
+ title: 'Stress Test (20 items)',
250
+ subtitle: 'Many small equal segments',
251
+ segments: Array.from({ length: 20 }, (_, i) => ({
252
+ value: 5,
253
+ label: `S${i + 1}`,
254
+ })),
255
+ markdown: [
256
+ '## Stress Test',
257
+ '',
258
+ '20 equal segments at 5% each.',
259
+ 'Tests color cycling (7 colors, wraps around).',
260
+ 'Labels may be hidden when segments are narrow.',
261
+ ].join('\n'),
262
+ meta: [
263
+ { title: 'Segments', text: '20' },
264
+ { title: 'Colors', text: '7 (cycling)' },
265
+ ],
266
+ },
267
+ ]
268
+
269
+ // ── Full Detail view (pushed on Enter) ───────────────────────────────
270
+
271
+ function BarChartDetailView({ item }: { item: BarItem }): any {
272
+ const { pop } = useNavigation()
273
+
274
+ const markdown = [
275
+ `# ${item.title}`,
276
+ '',
277
+ item.subtitle,
278
+ '',
279
+ ...(item.markdown ? [item.markdown, ''] : []),
280
+ `**Segments:** ${item.segments.length} `,
281
+ `**Total:** ${item.segments.reduce((s, seg) => s + seg.value, 0).toLocaleString()}`,
282
+ ].join('\n')
283
+
284
+ return (
285
+ <Detail
286
+ navigationTitle={item.title}
287
+ markdown={markdown}
288
+ metadata={
289
+ <Detail.Metadata>
290
+ <BarChart height={1}>
291
+ {item.segments.map((seg, i) => {
292
+ return (
293
+ <BarChart.Segment
294
+ key={i}
295
+ value={seg.value}
296
+ label={seg.label}
297
+ color={seg.color}
298
+ />
299
+ )
300
+ })}
301
+ </BarChart>
302
+ {Boolean(item.lineData) && (
303
+ <>
304
+ <Detail.Metadata.Separator />
305
+ <Graph
306
+ height={10}
307
+ xLabels={item.lineData!.xLabels}
308
+ variant="area"
309
+ yFormat={(v) => v.toFixed(0)}
310
+ >
311
+ <Graph.Line data={item.lineData!.data} color={Color.Orange} />
312
+ </Graph>
313
+ </>
314
+ )}
315
+ <Detail.Metadata.Separator />
316
+ {item.meta.map((m) => {
317
+ return (
318
+ <Detail.Metadata.Label
319
+ key={m.title}
320
+ title={m.title}
321
+ text={m.color ? { value: m.text, color: m.color } : m.text}
322
+ />
323
+ )
324
+ })}
325
+ </Detail.Metadata>
326
+ }
327
+ actions={
328
+ <ActionPanel>
329
+ <Action title="Go Back" onAction={() => { pop() }} />
330
+ </ActionPanel>
331
+ }
332
+ />
333
+ )
334
+ }
335
+
336
+ // ── Main list ────────────────────────────────────────────────────────
337
+
338
+ function GraphBarChartExample() {
339
+ const { push } = useNavigation()
340
+
341
+ return (
342
+ <List navigationTitle="BarChart Showcase" isShowingDetail={true}>
343
+ {items.map((item) => {
344
+ return (
345
+ <List.Item
346
+ key={item.title}
347
+ title={item.title}
348
+ subtitle={item.subtitle}
349
+ detail={
350
+ <List.Item.Detail
351
+ metadata={
352
+ <List.Item.Detail.Metadata>
353
+ <BarChart height={1}>
354
+ {item.segments.map((seg, i) => {
355
+ return (
356
+ <BarChart.Segment
357
+ key={i}
358
+ value={seg.value}
359
+ label={seg.label}
360
+ color={seg.color}
361
+ />
362
+ )
363
+ })}
364
+ </BarChart>
365
+ <List.Item.Detail.Metadata.Separator />
366
+ {item.meta.map((m) => {
367
+ return (
368
+ <List.Item.Detail.Metadata.Label
369
+ key={m.title}
370
+ title={m.title}
371
+ text={m.color ? { value: m.text, color: m.color } : m.text}
372
+ />
373
+ )
374
+ })}
375
+ {Boolean(item.lineData) && (
376
+ <>
377
+ <List.Item.Detail.Metadata.Separator />
378
+ <Graph
379
+ height={6}
380
+ xLabels={item.lineData!.xLabels}
381
+ variant="area"
382
+ yTicks={3}
383
+ yFormat={(v) => v.toFixed(0)}
384
+ >
385
+ <Graph.Line data={item.lineData!.data} color={Color.Orange} />
386
+ </Graph>
387
+ </>
388
+ )}
389
+ </List.Item.Detail.Metadata>
390
+ }
391
+ />
392
+ }
393
+ actions={
394
+ <ActionPanel>
395
+ <Action
396
+ title="Open Detail"
397
+ onAction={() => { push(<BarChartDetailView item={item} />) }}
398
+ />
399
+ </ActionPanel>
400
+ }
401
+ />
402
+ )
403
+ })}
404
+ </List>
405
+ )
406
+ }
407
+
408
+ renderWithProviders(<GraphBarChartExample />)