termcast 1.4.0 → 1.5.0
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 +8 -7
- package/dist/build.js.map +1 -1
- package/dist/cli.js +0 -40
- package/dist/cli.js.map +1 -1
- package/dist/components/bar-graph.d.ts +23 -8
- package/dist/components/bar-graph.d.ts.map +1 -1
- package/dist/components/bar-graph.js +84 -40
- package/dist/components/bar-graph.js.map +1 -1
- package/dist/components/dotted-line-graph.d.ts +86 -0
- package/dist/components/dotted-line-graph.d.ts.map +1 -0
- package/dist/components/dotted-line-graph.js +260 -0
- package/dist/components/dotted-line-graph.js.map +1 -0
- package/dist/components/extension-preferences.d.ts.map +1 -1
- package/dist/components/extension-preferences.js +1 -10
- package/dist/components/extension-preferences.js.map +1 -1
- package/dist/components/graph.d.ts.map +1 -1
- package/dist/components/graph.js +7 -1
- package/dist/components/graph.js.map +1 -1
- package/dist/components/histogram.d.ts +42 -0
- package/dist/components/histogram.d.ts.map +1 -0
- package/dist/components/histogram.js +115 -0
- package/dist/components/histogram.js.map +1 -0
- package/dist/components/horizontal-bar-graph.d.ts +47 -0
- package/dist/components/horizontal-bar-graph.d.ts.map +1 -0
- package/dist/components/horizontal-bar-graph.js +137 -0
- package/dist/components/horizontal-bar-graph.js.map +1 -0
- package/dist/components/list.d.ts +2 -0
- package/dist/components/list.d.ts.map +1 -1
- package/dist/components/list.js +10 -10
- package/dist/components/list.js.map +1 -1
- package/dist/examples/bar-graph-weekly.js +2 -2
- package/dist/examples/bar-graph-weekly.js.map +1 -1
- package/dist/examples/charts-showcase-barchart.d.ts +2 -0
- package/dist/examples/charts-showcase-barchart.d.ts.map +1 -0
- package/dist/examples/charts-showcase-barchart.js +10 -0
- package/dist/examples/charts-showcase-barchart.js.map +1 -0
- package/dist/examples/charts-showcase-bargraph.d.ts +2 -0
- package/dist/examples/charts-showcase-bargraph.d.ts.map +1 -0
- package/dist/examples/charts-showcase-bargraph.js +60 -0
- package/dist/examples/charts-showcase-bargraph.js.map +1 -0
- package/dist/examples/charts-showcase-candle.d.ts +2 -0
- package/dist/examples/charts-showcase-candle.d.ts.map +1 -0
- package/dist/examples/charts-showcase-candle.js +30 -0
- package/dist/examples/charts-showcase-candle.js.map +1 -0
- package/dist/examples/charts-showcase-graph.d.ts +2 -0
- package/dist/examples/charts-showcase-graph.d.ts.map +1 -0
- package/dist/examples/charts-showcase-graph.js +33 -0
- package/dist/examples/charts-showcase-graph.js.map +1 -0
- package/dist/examples/charts-showcase-heatmap.d.ts +2 -0
- package/dist/examples/charts-showcase-heatmap.d.ts.map +1 -0
- package/dist/examples/charts-showcase-heatmap.js +36 -0
- package/dist/examples/charts-showcase-heatmap.js.map +1 -0
- package/dist/examples/charts-showcase-mixed.d.ts +2 -0
- package/dist/examples/charts-showcase-mixed.d.ts.map +1 -0
- package/dist/examples/charts-showcase-mixed.js +30 -0
- package/dist/examples/charts-showcase-mixed.js.map +1 -0
- package/dist/examples/charts-showcase-progress.d.ts +2 -0
- package/dist/examples/charts-showcase-progress.d.ts.map +1 -0
- package/dist/examples/charts-showcase-progress.js +10 -0
- package/dist/examples/charts-showcase-progress.js.map +1 -0
- package/dist/examples/graph-multi-series.js +1 -1
- package/dist/examples/graph-multi-series.js.map +1 -1
- package/dist/examples/horizontal-bar-graph-weekly.d.ts +2 -0
- package/dist/examples/horizontal-bar-graph-weekly.d.ts.map +1 -0
- package/dist/examples/horizontal-bar-graph-weekly.js +67 -0
- package/dist/examples/horizontal-bar-graph-weekly.js.map +1 -0
- package/dist/examples/simple-dotted-line-graph.d.ts +2 -0
- package/dist/examples/simple-dotted-line-graph.d.ts.map +1 -0
- package/dist/examples/simple-dotted-line-graph.js +39 -0
- package/dist/examples/simple-dotted-line-graph.js.map +1 -0
- package/dist/examples/simple-histogram.d.ts +2 -0
- package/dist/examples/simple-histogram.d.ts.map +1 -0
- package/dist/examples/simple-histogram.js +47 -0
- package/dist/examples/simple-histogram.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +15 -6
- package/dist/logger.js.map +1 -1
- package/dist/platform/node/sqlite.d.ts +6 -5
- package/dist/platform/node/sqlite.d.ts.map +1 -1
- package/dist/platform/node/sqlite.js +30 -14
- package/dist/platform/node/sqlite.js.map +1 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/theme.js +11 -9
- package/dist/theme.js.map +1 -1
- package/dist/utils/run-command.d.ts.map +1 -1
- package/dist/utils/run-command.js +8 -19
- package/dist/utils/run-command.js.map +1 -1
- package/dist/utils.d.ts +1 -19
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -100
- package/dist/utils.js.map +1 -1
- package/package.json +14 -16
- package/src/build.tsx +11 -10
- package/src/cli.tsx +3 -40
- package/src/compile.vitest.tsx +3 -3
- package/src/components/bar-graph.tsx +217 -111
- package/src/components/dotted-line-graph.tsx +407 -0
- package/src/components/extension-preferences.tsx +2 -12
- package/src/components/graph.tsx +5 -1
- package/src/components/histogram.tsx +228 -0
- package/src/components/horizontal-bar-graph.tsx +279 -0
- package/src/components/list.tsx +20 -15
- package/src/examples/action-shortcut.vitest.tsx +17 -17
- package/src/examples/bar-graph-weekly.tsx +2 -2
- package/src/examples/bar-graph-weekly.vitest.tsx +63 -62
- package/src/examples/charts-showcase-bargraph.tsx +103 -0
- package/src/examples/detail-metadata-showcase.vitest.tsx +13 -18
- package/src/examples/form-basic.vitest.tsx +35 -35
- package/src/examples/form-dropdown.vitest.tsx +11 -11
- package/src/examples/form-scroll.vitest.tsx +1 -1
- package/src/examples/form-tagpicker.vitest.tsx +11 -11
- package/src/examples/github.vitest.tsx +22 -22
- package/src/examples/graph-bar-chart.vitest.tsx +8 -8
- package/src/examples/graph-multi-series.tsx +1 -1
- package/src/examples/graph-row.vitest.tsx +14 -14
- package/src/examples/graph-styles.vitest.tsx +77 -77
- package/src/examples/horizontal-bar-graph-weekly.tsx +138 -0
- package/src/examples/horizontal-bar-graph-weekly.vitest.tsx +164 -0
- package/src/examples/list-detail-metadata.vitest.tsx +4 -4
- package/src/examples/list-with-detail.vitest.tsx +46 -46
- package/src/examples/simple-candle-chart.vitest.tsx +8 -8
- package/src/examples/simple-dotted-line-graph.tsx +53 -0
- package/src/examples/simple-dotted-line-graph.vitest.tsx +62 -0
- package/src/examples/simple-grid.vitest.tsx +4 -4
- package/src/examples/simple-histogram.tsx +90 -0
- package/src/examples/simple-navigation.vitest.tsx +4 -4
- package/src/examples/swift-extension.vitest.tsx +3 -3
- package/src/examples/toast-variations.vitest.tsx +5 -5
- package/src/extensions/dev.vitest.tsx +8 -8
- package/src/index.tsx +21 -0
- package/src/logger.tsx +16 -6
- package/src/platform/node/sqlite.ts +29 -13
- package/src/theme.tsx +11 -10
- package/src/utils/run-command.tsx +10 -19
- package/src/utils.tsx +0 -163
- package/src/examples/store.tsx +0 -4
- package/src/examples/store.vitest.tsx +0 -78
- package/src/extensions/home.tsx +0 -227
- package/src/extensions/store.tsx +0 -375
|
@@ -19,7 +19,7 @@ afterEach(() => {
|
|
|
19
19
|
test('area style renders braille characters', async () => {
|
|
20
20
|
const text = await session.text({
|
|
21
21
|
waitFor: (text) => {
|
|
22
|
-
return
|
|
22
|
+
return /Area.*Price/i.test(text) && text.includes('│')
|
|
23
23
|
},
|
|
24
24
|
timeout: 10000,
|
|
25
25
|
})
|
|
@@ -32,19 +32,19 @@ test('area style renders braille characters', async () => {
|
|
|
32
32
|
|
|
33
33
|
> Search...
|
|
34
34
|
|
|
35
|
-
›Area -
|
|
36
|
-
Area -
|
|
37
|
-
Area
|
|
38
|
-
Area
|
|
39
|
-
Filled
|
|
40
|
-
Filled
|
|
41
|
-
Filled
|
|
42
|
-
Filled
|
|
43
|
-
Striped
|
|
44
|
-
Striped
|
|
45
|
-
Striped
|
|
46
|
-
Striped
|
|
47
|
-
Striped
|
|
35
|
+
›Area - ...k Price Orange ...lle dots │ 211│ ⣠ ▲
|
|
36
|
+
Area - ... Series CPU + M... overlay │ │ ⢀⣴⣦⣼⣿ █
|
|
37
|
+
Area...ave Purple + Ma...sine/cosine │ │ ⢠⣦⣄⣴⣿⣿⣿⣿⣿ █
|
|
38
|
+
Area -...evenue Single s...uto range │ 189│ ⢀⣴⣷⣦⣿⣿⣿⣿⣿⣿⣿⣿⣿ █
|
|
39
|
+
Filled...RevenueSolid bl...wth chart │ │ ⣠⣀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ▀
|
|
40
|
+
Filled...en TempDaily te...ure curve │ │ ⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
41
|
+
Filled ...low CPUHigh con... on dark │ 167│ ⢀⣴⣿⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
42
|
+
Filled ...a WavesSmooth c...h blocks │ │ ⣰⣤⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
43
|
+
Striped...e/Orang Warm al...g colors │ │⢀⣴⡄⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
44
|
+
Striped...lue/Re High con... stripes │ 145│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
45
|
+
Striped...Defaul primary ...no prop) │ 1 5 10 15 20
|
|
46
|
+
Striped -...en/YellowNature-inspired │
|
|
47
|
+
Striped .../MagentaWarm gr...nt feel │ ─────────────────────────────────
|
|
48
48
|
│
|
|
49
49
|
│ Variant: area
|
|
50
50
|
↵ open detail ↑↓ navigate ^k act │ ▼
|
|
@@ -53,7 +53,7 @@ test('area style renders braille characters', async () => {
|
|
|
53
53
|
`)
|
|
54
54
|
|
|
55
55
|
expect(text).toMatch(/[\u2800-\u28FF]/)
|
|
56
|
-
expect(text).toContain('
|
|
56
|
+
expect(text).toContain('Price')
|
|
57
57
|
}, 30000)
|
|
58
58
|
|
|
59
59
|
test('filled style renders block characters', async () => {
|
|
@@ -71,7 +71,7 @@ test('filled style renders block characters', async () => {
|
|
|
71
71
|
|
|
72
72
|
const text = await session.text({
|
|
73
73
|
waitFor: (text) => {
|
|
74
|
-
return
|
|
74
|
+
return /›Filled.*Revenue/i.test(text)
|
|
75
75
|
},
|
|
76
76
|
timeout: 5000,
|
|
77
77
|
})
|
|
@@ -84,19 +84,19 @@ test('filled style renders block characters', async () => {
|
|
|
84
84
|
|
|
85
85
|
> Search...
|
|
86
86
|
|
|
87
|
-
Area -
|
|
88
|
-
Area -
|
|
89
|
-
Area
|
|
90
|
-
Area
|
|
91
|
-
›Filled
|
|
92
|
-
Filled
|
|
93
|
-
Filled
|
|
94
|
-
Filled
|
|
95
|
-
Striped
|
|
96
|
-
Striped
|
|
97
|
-
Striped
|
|
98
|
-
Striped
|
|
99
|
-
Striped
|
|
87
|
+
Area - ...k Price Orange ...lle dots │ Revenue Growth ▲
|
|
88
|
+
Area - ... Series CPU + M... overlay │ █
|
|
89
|
+
Area...ave Purple + Ma...sine/cosine │
|
|
90
|
+
Area -...evenue Single s...uto range │ Quarterly revenue from $10k** to
|
|
91
|
+
›Filled...RevenueSolid bl...wth chart │ **$75k.
|
|
92
|
+
Filled...en TempDaily te...ure curve │ Q1: $10k → Q2: $25k (+150%)
|
|
93
|
+
Filled ...low CPUHigh con... on dark │ Q2: $25k → Q3: $50k (+100%)
|
|
94
|
+
Filled ...a WavesSmooth c...h blocks │ Q3: $50k → Q4: $75k (+50%)
|
|
95
|
+
Striped...e/Orang Warm al...g colors │
|
|
96
|
+
Striped...lue/Re High con... stripes │ 78│ ▖
|
|
97
|
+
Striped...Defaul primary ...no prop) │ │ ▖▌▖▌▌
|
|
98
|
+
Striped -...en/YellowNature-inspired │ │ ▖▖▖▌▌▌▌▌▌
|
|
99
|
+
Striped .../MagentaWarm gr...nt feel │ 54│ ▖▌▌▌▌▌▌▌▌▌▌
|
|
100
100
|
│ │ ▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌
|
|
101
101
|
│ │ ▖ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
102
102
|
↵ open detail ↑↓ navigate ^k act │ 31│ ▖▌▌▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ ▼
|
|
@@ -105,7 +105,7 @@ test('filled style renders block characters', async () => {
|
|
|
105
105
|
`)
|
|
106
106
|
|
|
107
107
|
expect(text).toMatch(/[▌▘▖]/)
|
|
108
|
-
expect(text).toContain('›Filled
|
|
108
|
+
expect(text).toContain('›Filled')
|
|
109
109
|
}, 30000)
|
|
110
110
|
|
|
111
111
|
test('striped style renders alternating columns', async () => {
|
|
@@ -123,7 +123,7 @@ test('striped style renders alternating columns', async () => {
|
|
|
123
123
|
|
|
124
124
|
const text = await session.text({
|
|
125
125
|
waitFor: (text) => {
|
|
126
|
-
return
|
|
126
|
+
return /›Striped.*Warm/i.test(text)
|
|
127
127
|
},
|
|
128
128
|
timeout: 5000,
|
|
129
129
|
})
|
|
@@ -136,19 +136,19 @@ test('striped style renders alternating columns', async () => {
|
|
|
136
136
|
|
|
137
137
|
> Search...
|
|
138
138
|
|
|
139
|
-
Area -
|
|
140
|
-
Area -
|
|
141
|
-
Area
|
|
142
|
-
Area
|
|
143
|
-
Filled
|
|
144
|
-
Filled
|
|
145
|
-
Filled
|
|
146
|
-
Filled
|
|
147
|
-
›Striped
|
|
148
|
-
Striped
|
|
149
|
-
Striped
|
|
150
|
-
Striped
|
|
151
|
-
Striped
|
|
139
|
+
Area - ...k Price Orange ...lle dots │ 211│ ▖ ▲
|
|
140
|
+
Area - ... Series CPU + M... overlay │ │ ▖▖▌▌ █
|
|
141
|
+
Area...ave Purple + Ma...sine/cosine │ │ ▖▖▖▌▌▌▌▌ █
|
|
142
|
+
Area -...evenue Single s...uto range │ 189│ ▖▖▌▖▌▌▌▌▌▌▌▌▌
|
|
143
|
+
Filled...RevenueSolid bl...wth chart │ │ ▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
144
|
+
Filled...en TempDaily te...ure curve │ │ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
145
|
+
Filled ...low CPUHigh con... on dark │ 167│ ▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
146
|
+
Filled ...a WavesSmooth c...h blocks │ │ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
147
|
+
›Striped...e/Orang Warm al...g colors │ │▖▌▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
148
|
+
Striped...lue/Re High con... stripes │ 145│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
|
|
149
|
+
Striped...Defaul primary ...no prop) │ 1 5 10 15 20
|
|
150
|
+
Striped -...en/YellowNature-inspired │
|
|
151
|
+
Striped .../MagentaWarm gr...nt feel │ ─────────────────────────────────
|
|
152
152
|
│
|
|
153
153
|
│ Even cols: Purple
|
|
154
154
|
↵ open detail ↑↓ navigate ^k act │ ▼
|
|
@@ -157,13 +157,13 @@ test('striped style renders alternating columns', async () => {
|
|
|
157
157
|
`)
|
|
158
158
|
|
|
159
159
|
expect(text).toMatch(/[▌▘▖]/)
|
|
160
|
-
expect(text).toContain('›Striped
|
|
160
|
+
expect(text).toContain('›Striped')
|
|
161
161
|
}, 30000)
|
|
162
162
|
|
|
163
163
|
test('markdown + metadata detail view in list', async () => {
|
|
164
164
|
await session.text({
|
|
165
165
|
waitFor: (text) => {
|
|
166
|
-
return
|
|
166
|
+
return /Area.*Series/i.test(text) && text.includes('│')
|
|
167
167
|
},
|
|
168
168
|
timeout: 10000,
|
|
169
169
|
})
|
|
@@ -173,7 +173,7 @@ test('markdown + metadata detail view in list', async () => {
|
|
|
173
173
|
|
|
174
174
|
const text = await session.text({
|
|
175
175
|
waitFor: (text) => {
|
|
176
|
-
return
|
|
176
|
+
return /›Area.*Series/i.test(text) && text.includes('System Metrics')
|
|
177
177
|
},
|
|
178
178
|
timeout: 5000,
|
|
179
179
|
})
|
|
@@ -186,19 +186,19 @@ test('markdown + metadata detail view in list', async () => {
|
|
|
186
186
|
|
|
187
187
|
> Search...
|
|
188
188
|
|
|
189
|
-
Area -
|
|
190
|
-
›Area -
|
|
191
|
-
Area
|
|
192
|
-
Area
|
|
193
|
-
Filled
|
|
194
|
-
Filled
|
|
195
|
-
Filled
|
|
196
|
-
Filled
|
|
197
|
-
Striped
|
|
198
|
-
Striped
|
|
199
|
-
Striped
|
|
200
|
-
Striped
|
|
201
|
-
Striped
|
|
189
|
+
Area - ...k Price Orange ...lle dots │ System Metrics ▲
|
|
190
|
+
›Area - ... Series CPU + M... overlay │ ▀
|
|
191
|
+
Area...ave Purple + Ma...sine/cosine │
|
|
192
|
+
Area -...evenue Single s...uto range │ CPU usage (blue) vs memory usage (
|
|
193
|
+
Filled...RevenueSolid bl...wth chart │ green) over 24 hours.
|
|
194
|
+
Filled...en TempDaily te...ure curve │ - Peak CPU at 90% around 15h
|
|
195
|
+
Filled ...low CPUHigh con... on dark │ - Memory steadily climbing to 86%
|
|
196
|
+
Filled ...a WavesSmooth c...h blocks │ - CPU has high variance, memory
|
|
197
|
+
Striped...e/Orang Warm al...g colors │ is monotonic
|
|
198
|
+
Striped...lue/Re High con... stripes │
|
|
199
|
+
Striped...Defaul primary ...no prop) │ 100│
|
|
200
|
+
Striped -...en/YellowNature-inspired │ │ ⣠⣶⣧ ⣀⣠⣤⣶
|
|
201
|
+
Striped .../MagentaWarm gr...nt feel │ 75│ ⢀⣴⣧ ⢀⣰⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿
|
|
202
202
|
│ │ ⢀⣾⣿⣿⣧⢀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
203
203
|
│ │ ⢀⣾⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
204
204
|
↵ open detail ↑↓ navigate ^k act │ 50│⣀⣀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ▼
|
|
@@ -213,7 +213,7 @@ test('markdown + metadata detail view in list', async () => {
|
|
|
213
213
|
test('enter pushes full detail view with graph', async () => {
|
|
214
214
|
await session.text({
|
|
215
215
|
waitFor: (text) => {
|
|
216
|
-
return
|
|
216
|
+
return /Area.*Price/i.test(text) && text.includes('│')
|
|
217
217
|
},
|
|
218
218
|
timeout: 10000,
|
|
219
219
|
})
|
|
@@ -265,7 +265,7 @@ test('enter pushes full detail view with graph', async () => {
|
|
|
265
265
|
test('esc returns from detail to list', async () => {
|
|
266
266
|
await session.text({
|
|
267
267
|
waitFor: (text) => {
|
|
268
|
-
return
|
|
268
|
+
return /Area.*Price/i.test(text) && text.includes('│')
|
|
269
269
|
},
|
|
270
270
|
timeout: 10000,
|
|
271
271
|
})
|
|
@@ -284,7 +284,7 @@ test('esc returns from detail to list', async () => {
|
|
|
284
284
|
|
|
285
285
|
const text = await session.text({
|
|
286
286
|
waitFor: (text) => {
|
|
287
|
-
return
|
|
287
|
+
return /›Area.*Price/i.test(text) && text.includes('Graph Styles')
|
|
288
288
|
},
|
|
289
289
|
timeout: 5000,
|
|
290
290
|
})
|
|
@@ -297,19 +297,19 @@ test('esc returns from detail to list', async () => {
|
|
|
297
297
|
|
|
298
298
|
> Search...
|
|
299
299
|
|
|
300
|
-
›Area -
|
|
301
|
-
Area -
|
|
302
|
-
Area
|
|
303
|
-
Area
|
|
304
|
-
Filled
|
|
305
|
-
Filled
|
|
306
|
-
Filled
|
|
307
|
-
Filled
|
|
308
|
-
Striped
|
|
309
|
-
Striped
|
|
310
|
-
Striped
|
|
311
|
-
Striped
|
|
312
|
-
Striped
|
|
300
|
+
›Area - ...k Price Orange ...lle dots │ 211│ ⣠ ▲
|
|
301
|
+
Area - ... Series CPU + M... overlay │ │ ⢀⣴⣦⣼⣿ █
|
|
302
|
+
Area...ave Purple + Ma...sine/cosine │ │ ⢠⣦⣄⣴⣿⣿⣿⣿⣿ █
|
|
303
|
+
Area -...evenue Single s...uto range │ 189│ ⢀⣴⣷⣦⣿⣿⣿⣿⣿⣿⣿⣿⣿ █
|
|
304
|
+
Filled...RevenueSolid bl...wth chart │ │ ⣠⣀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ ▀
|
|
305
|
+
Filled...en TempDaily te...ure curve │ │ ⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
306
|
+
Filled ...low CPUHigh con... on dark │ 167│ ⢀⣴⣿⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
307
|
+
Filled ...a WavesSmooth c...h blocks │ │ ⣰⣤⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
308
|
+
Striped...e/Orang Warm al...g colors │ │⢀⣴⡄⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
309
|
+
Striped...lue/Re High con... stripes │ 145│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
|
310
|
+
Striped...Defaul primary ...no prop) │ 1 5 10 15 20
|
|
311
|
+
Striped -...en/YellowNature-inspired │
|
|
312
|
+
Striped .../MagentaWarm gr...nt feel │ ─────────────────────────────────
|
|
313
313
|
│
|
|
314
314
|
│ Variant: area
|
|
315
315
|
↵ open detail ↑↓ navigate ^k act │ ▼
|
|
@@ -317,6 +317,6 @@ test('esc returns from detail to list', async () => {
|
|
|
317
317
|
"
|
|
318
318
|
`)
|
|
319
319
|
|
|
320
|
-
expect(text).toContain('›Area
|
|
320
|
+
expect(text).toContain('›Area')
|
|
321
321
|
expect(text).toContain('Graph Styles')
|
|
322
322
|
}, 30000)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Example: HorizontalBarGraph stacked horizontal rows with a compact right legend.
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Action, ActionPanel, Detail, HorizontalBarGraph, List } from 'termcast'
|
|
5
|
+
import { useNavigation } from 'termcast/src/internal/navigation'
|
|
6
|
+
import { renderWithProviders } from '../utils'
|
|
7
|
+
|
|
8
|
+
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
|
|
9
|
+
|
|
10
|
+
interface DataSet {
|
|
11
|
+
title: string
|
|
12
|
+
subtitle: string
|
|
13
|
+
labels: string[]
|
|
14
|
+
categoryTitle?: string
|
|
15
|
+
distributionTitle?: string
|
|
16
|
+
legendTitle?: string
|
|
17
|
+
series: Array<{ data: number[]; title: string }>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const dataSets: DataSet[] = [
|
|
21
|
+
{
|
|
22
|
+
title: 'Weekly Traffic',
|
|
23
|
+
subtitle: 'Direct / Organic / Referral across 6 days',
|
|
24
|
+
labels: days,
|
|
25
|
+
series: [
|
|
26
|
+
{ data: [40, 30, 25, 15, 50, 40], title: 'Direct' },
|
|
27
|
+
{ data: [30, 35, 15, 20, 35, 30], title: 'Organic' },
|
|
28
|
+
{ data: [20, 25, 10, 10, 25, 20], title: 'Referral' },
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
title: 'Revenue by Region',
|
|
33
|
+
subtitle: 'Americas / EMEA / APAC',
|
|
34
|
+
labels: days,
|
|
35
|
+
series: [
|
|
36
|
+
{ data: [60, 45, 30, 55, 70, 50], title: 'Americas' },
|
|
37
|
+
{ data: [25, 30, 20, 35, 25, 30], title: 'EMEA' },
|
|
38
|
+
{ data: [15, 20, 10, 10, 20, 15], title: 'APAC' },
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
title: 'Long Labels',
|
|
43
|
+
subtitle: 'The left label column truncates without stealing legend space',
|
|
44
|
+
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday & Sunday'],
|
|
45
|
+
categoryTitle: 'day',
|
|
46
|
+
distributionTitle: 'traffic',
|
|
47
|
+
legendTitle: 'source',
|
|
48
|
+
series: [
|
|
49
|
+
{ data: [40, 30, 25, 15, 50, 40], title: 'Views' },
|
|
50
|
+
{ data: [20, 25, 10, 10, 25, 20], title: 'Clicks' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: 'Many Series',
|
|
55
|
+
subtitle: 'Legend grows only as wide as its content needs',
|
|
56
|
+
labels: days,
|
|
57
|
+
series: Array.from({ length: 8 }, (_, i) => {
|
|
58
|
+
return {
|
|
59
|
+
data: [10 + i * 5, 15 + i * 3, 8 + i * 4, 12 + i * 2, 20 + i * 6, 5 + i * 7],
|
|
60
|
+
title: `Series ${i + 1}`,
|
|
61
|
+
}
|
|
62
|
+
}),
|
|
63
|
+
},
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
function Chart({ item, height }: { item: DataSet; height: number }): any {
|
|
67
|
+
return (
|
|
68
|
+
<HorizontalBarGraph
|
|
69
|
+
labels={item.labels}
|
|
70
|
+
height={height}
|
|
71
|
+
categoryTitle={item.categoryTitle}
|
|
72
|
+
distributionTitle={item.distributionTitle}
|
|
73
|
+
legendTitle={item.legendTitle}
|
|
74
|
+
>
|
|
75
|
+
{item.series.map((series) => {
|
|
76
|
+
return <HorizontalBarGraph.Series key={series.title} data={series.data} title={series.title} />
|
|
77
|
+
})}
|
|
78
|
+
</HorizontalBarGraph>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function HorizontalBarGraphDetailView({ item }: { item: DataSet }): any {
|
|
83
|
+
const { pop } = useNavigation()
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<Detail
|
|
87
|
+
navigationTitle={item.title}
|
|
88
|
+
markdown={`# ${item.title}\n\n${item.subtitle}`}
|
|
89
|
+
metadata={
|
|
90
|
+
<Detail.Metadata>
|
|
91
|
+
<Chart item={item} height={12} />
|
|
92
|
+
</Detail.Metadata>
|
|
93
|
+
}
|
|
94
|
+
actions={
|
|
95
|
+
<ActionPanel>
|
|
96
|
+
<Action title="Go Back" onAction={() => { pop() }} />
|
|
97
|
+
</ActionPanel>
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function HorizontalBarGraphWeeklyExample() {
|
|
104
|
+
const { push } = useNavigation()
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<List navigationTitle="HorizontalBarGraph Showcase" isShowingDetail={true}>
|
|
108
|
+
{dataSets.map((item) => {
|
|
109
|
+
return (
|
|
110
|
+
<List.Item
|
|
111
|
+
key={item.title}
|
|
112
|
+
title={item.title}
|
|
113
|
+
subtitle={item.subtitle}
|
|
114
|
+
detail={
|
|
115
|
+
<List.Item.Detail
|
|
116
|
+
metadata={
|
|
117
|
+
<List.Item.Detail.Metadata>
|
|
118
|
+
<Chart item={item} height={10} />
|
|
119
|
+
</List.Item.Detail.Metadata>
|
|
120
|
+
}
|
|
121
|
+
/>
|
|
122
|
+
}
|
|
123
|
+
actions={
|
|
124
|
+
<ActionPanel>
|
|
125
|
+
<Action
|
|
126
|
+
title="Open Detail"
|
|
127
|
+
onAction={() => { push(<HorizontalBarGraphDetailView item={item} />) }}
|
|
128
|
+
/>
|
|
129
|
+
</ActionPanel>
|
|
130
|
+
}
|
|
131
|
+
/>
|
|
132
|
+
)
|
|
133
|
+
})}
|
|
134
|
+
</List>
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
void renderWithProviders(<HorizontalBarGraphWeeklyExample />)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// E2E tests for HorizontalBarGraph stacked horizontal rows and right-side legend.
|
|
2
|
+
|
|
3
|
+
import { afterEach, beforeEach, expect, test } from 'vitest'
|
|
4
|
+
import { launchTerminal, Session } from 'tuistory/src'
|
|
5
|
+
|
|
6
|
+
let session: Session
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
session = await launchTerminal({
|
|
10
|
+
command: 'bun',
|
|
11
|
+
args: ['src/examples/horizontal-bar-graph-weekly.tsx'],
|
|
12
|
+
cols: 90,
|
|
13
|
+
rows: 30,
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
session?.close()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('renders horizontal stacked rows and compact legend', async () => {
|
|
22
|
+
const text = await session.text({
|
|
23
|
+
waitFor: (content) => {
|
|
24
|
+
return content.includes('Mon') && content.includes('Direct') && content.includes('%')
|
|
25
|
+
},
|
|
26
|
+
timeout: 10000,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(text).toMatchInlineSnapshot(`
|
|
30
|
+
"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
HorizontalBarGraph Showcase ────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
> Search...
|
|
36
|
+
|
|
37
|
+
›Wee...fficDirect / Organ... across 6 days │ category distribution legend
|
|
38
|
+
Revenue by Region Americas / EMEA / APAC │ ──────── ──────────── ───────────────
|
|
39
|
+
Lon...el The left label...ng legend space │ Mon ╻╻╻╻╻╻╻╻╻╻ ● Direct 42%
|
|
40
|
+
Man...ie Legend grows o...s content needs │ Tue ╻╻╻╻╻╻╻╻╻╻ ● Organic 35%
|
|
41
|
+
│ Wed ╻╻╻╻╻ ● Referral 23%
|
|
42
|
+
│ Thu ╻╻╻╻╻
|
|
43
|
+
│ Fri ╻╻╻╻╻╻╻╻╻╻╻╻
|
|
44
|
+
│ Sat ╻╻╻╻╻╻╻╻╻╻
|
|
45
|
+
↵ open detail ↑↓ navigate ^k actions │
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
"
|
|
61
|
+
`)
|
|
62
|
+
expect(text).toContain('Mon')
|
|
63
|
+
expect(text).toContain('Direct')
|
|
64
|
+
expect(text).toContain('╻')
|
|
65
|
+
}, 30000)
|
|
66
|
+
|
|
67
|
+
test('long labels truncate and leave legend visible', async () => {
|
|
68
|
+
await session.text({ waitFor: (content) => content.includes('Lon...el'), timeout: 10000 })
|
|
69
|
+
session.sendKey('down')
|
|
70
|
+
session.sendKey('down')
|
|
71
|
+
|
|
72
|
+
const text = await session.text({
|
|
73
|
+
waitFor: (content) => {
|
|
74
|
+
return content.includes('›Lon...el') && content.includes('Views')
|
|
75
|
+
},
|
|
76
|
+
timeout: 10000,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
expect(text).toMatchInlineSnapshot(`
|
|
80
|
+
"
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
HorizontalBarGraph Showcase ────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
> Search...
|
|
86
|
+
|
|
87
|
+
Wee...fficDirect / Organ... across 6 days │ day traffi source
|
|
88
|
+
Revenue by Region Americas / EMEA / APAC │ ──────────────── ────── ─────────────
|
|
89
|
+
›Lon...el The left label...ng legend space │ Monday ╻╻╻╻╻ ● Views 65%
|
|
90
|
+
Man...ie Legend grows o...s content needs │ Tuesday ╻╻╻╻ ● Clicks 35%
|
|
91
|
+
│ Wednesday ╻╻╻
|
|
92
|
+
│ Thursday ╻╻
|
|
93
|
+
│ Friday ╻╻╻╻╻╻
|
|
94
|
+
│ Saturday & Sund… ╻╻╻╻╻
|
|
95
|
+
↵ open detail ↑↓ navigate ^k actions │
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
"
|
|
111
|
+
`)
|
|
112
|
+
expect(text).toContain('Saturday')
|
|
113
|
+
expect(text).toContain('Views')
|
|
114
|
+
}, 30000)
|
|
115
|
+
|
|
116
|
+
test('many series keeps bars readable and clips legend vertically', async () => {
|
|
117
|
+
await session.text({ waitFor: (content) => content.includes('Man...ie'), timeout: 10000 })
|
|
118
|
+
session.sendKey('down')
|
|
119
|
+
session.sendKey('down')
|
|
120
|
+
session.sendKey('down')
|
|
121
|
+
|
|
122
|
+
const text = await session.text({
|
|
123
|
+
waitFor: (content) => {
|
|
124
|
+
return content.includes('›Man...ie') && content.includes('Series 8')
|
|
125
|
+
},
|
|
126
|
+
timeout: 10000,
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
expect(text).toMatchInlineSnapshot(`
|
|
130
|
+
"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
HorizontalBarGraph Showcase ────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
> Search...
|
|
136
|
+
|
|
137
|
+
Wee...fficDirect / Organ... across 6 days │ category distribution legend
|
|
138
|
+
Revenue by Region Americas / EMEA / APAC │ ──────── ──────────── ───────────────
|
|
139
|
+
Lon...el The left label...ng legend space │ Mon ╻╻╻╻╻╻╻╻ ● Series 8 20%
|
|
140
|
+
›Man...ie Legend grows o...s content needs │ Tue ╻╻╻╻╻╻╻ ● Series 7 18%
|
|
141
|
+
│ Wed ╻╻╻╻╻╻ ● Series 6 16%
|
|
142
|
+
│ Thu ╻╻╻╻╻╻ ● Series 5 14%
|
|
143
|
+
│ Fri ╻╻╻╻╻╻╻╻╻╻╻╻ ● Series 4 11%
|
|
144
|
+
│ Sat ╻╻╻╻╻╻╻╻╻ ● Series 3 9%
|
|
145
|
+
↵ open detail ↑↓ navigate ^k actions │
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
"
|
|
161
|
+
`)
|
|
162
|
+
expect(text).toContain('Series 8')
|
|
163
|
+
expect(text).toContain('╻')
|
|
164
|
+
}, 30000)
|
|
@@ -157,10 +157,8 @@ test('list detail metadata renders colored values and tag lists', async () => {
|
|
|
157
157
|
> Search...
|
|
158
158
|
|
|
159
159
|
Short Values │ Project Status
|
|
160
|
-
Long Values │
|
|
161
|
-
›Colored & Tags │
|
|
162
|
-
│ Overview of the current project
|
|
163
|
-
│ state.
|
|
160
|
+
Long Values │ Overview of the current project
|
|
161
|
+
›Colored & Tags │ state.
|
|
164
162
|
│
|
|
165
163
|
│ Info
|
|
166
164
|
│
|
|
@@ -189,6 +187,8 @@ test('list detail metadata renders colored values and tag lists', async () => {
|
|
|
189
187
|
|
|
190
188
|
|
|
191
189
|
|
|
190
|
+
|
|
191
|
+
|
|
192
192
|
"
|
|
193
193
|
`)
|
|
194
194
|
|