termcast 1.3.51 → 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 (41) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +17 -12
  3. package/dist/app.js.map +1 -1
  4. package/dist/compile.d.ts.map +1 -1
  5. package/dist/compile.js +5 -2
  6. package/dist/compile.js.map +1 -1
  7. package/dist/components/actions.d.ts +4 -1
  8. package/dist/components/actions.d.ts.map +1 -1
  9. package/dist/components/actions.js +8 -5
  10. package/dist/components/actions.js.map +1 -1
  11. package/dist/components/detail.js +1 -1
  12. package/dist/components/detail.js.map +1 -1
  13. package/dist/components/footer.d.ts.map +1 -1
  14. package/dist/components/footer.js +1 -1
  15. package/dist/components/footer.js.map +1 -1
  16. package/dist/components/form/index.js +1 -1
  17. package/dist/components/form/index.js.map +1 -1
  18. package/dist/components/graph.d.ts.map +1 -1
  19. package/dist/components/graph.js +21 -25
  20. package/dist/components/graph.js.map +1 -1
  21. package/dist/components/heatmap.d.ts.map +1 -1
  22. package/dist/components/heatmap.js +24 -5
  23. package/dist/components/heatmap.js.map +1 -1
  24. package/dist/components/list.d.ts.map +1 -1
  25. package/dist/components/list.js +15 -10
  26. package/dist/components/list.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/app.tsx +17 -12
  29. package/src/compile.tsx +5 -2
  30. package/src/components/actions.tsx +9 -6
  31. package/src/components/detail.tsx +1 -1
  32. package/src/components/footer.tsx +3 -0
  33. package/src/components/form/index.tsx +1 -1
  34. package/src/components/graph.tsx +21 -24
  35. package/src/components/heatmap.tsx +23 -5
  36. package/src/components/list.tsx +16 -10
  37. package/src/examples/bar-graph-weekly.vitest.tsx +4 -4
  38. package/src/examples/graph-bar-chart.vitest.tsx +8 -8
  39. package/src/examples/graph-row.vitest.tsx +42 -42
  40. package/src/examples/graph-styles.vitest.tsx +19 -19
  41. package/src/examples/simple-heatmap.vitest.tsx +22 -22
@@ -1,9 +1,11 @@
1
1
  import {
2
2
  BoxRenderable,
3
+ MouseButton,
3
4
  ScrollBoxRenderable,
4
5
  TextAttributes,
5
6
  TextareaRenderable,
6
7
  } from '@opentui/core'
8
+ import type { MouseEvent as OpenTUIMouseEvent } from '@opentui/core'
7
9
  import { useKeyboard, flushSync } from '@opentui/react'
8
10
  import React, {
9
11
  ReactElement,
@@ -763,7 +765,7 @@ function ListItemRow(props: {
763
765
  accessories?: ItemAccessory[]
764
766
  active?: boolean
765
767
  isShowingDetail?: boolean
766
- onMouseDown?: () => void
768
+ onMouseDown?: (evt: OpenTUIMouseEvent) => void
767
769
  index?: number
768
770
  ref?: React.Ref<BoxRenderable>
769
771
  }) {
@@ -783,8 +785,8 @@ function ListItemRow(props: {
783
785
  }
784
786
  }
785
787
 
786
- const handleMouseDown = () => {
787
- props.onMouseDown?.()
788
+ const handleMouseDown = (evt: OpenTUIMouseEvent) => {
789
+ props.onMouseDown?.(evt)
788
790
  }
789
791
 
790
792
  const handleMouseOut = () => {
@@ -1391,9 +1393,9 @@ export const List: ListType = (props) => {
1391
1393
  .sort((a, b) => a.index - b.index)
1392
1394
  const currentItem = items.find((item) => item.index === selectedIndex)
1393
1395
 
1394
- // Handle Ctrl+K to show actions dialog via portal
1396
+ // Handle Ctrl+K / Cmd+K to show actions dialog via portal
1395
1397
  // Always open — built-in actions (Change Theme, etc.) are always available
1396
- if (evt.name === 'k' && evt.ctrl) {
1398
+ if (evt.name === 'k' && (evt.ctrl || evt.super)) {
1397
1399
  useStore.setState({ showActionsDialog: true })
1398
1400
  return
1399
1401
  }
@@ -1697,10 +1699,11 @@ const ListItem: ListItemType = (props) => {
1697
1699
  // Don't render if not visible
1698
1700
  if (!isVisible) return null
1699
1701
 
1700
- // Handle mouse click on item — always select and execute first action.
1702
+ // Handle mouse click on item — left-click selects and executes first action,
1703
+ // right-click selects and opens the actions dialog.
1701
1704
  // flushSync ensures React commits the new selectedIndex before Zustand
1702
1705
  // triggers auto-execute, so ActionPanel picks up the clicked item's actions.
1703
- const handleMouseDown = () => {
1706
+ const handleMouseDown = (evt: OpenTUIMouseEvent) => {
1704
1707
  if (listContext && index !== -1) {
1705
1708
  if (!isActive && listContext.setSelectedIndex) {
1706
1709
  const setIdx = listContext.setSelectedIndex
@@ -1708,7 +1711,10 @@ const ListItem: ListItemType = (props) => {
1708
1711
  setIdx(index)
1709
1712
  })
1710
1713
  }
1711
- if (props.actions) {
1714
+ if (evt.button === MouseButton.RIGHT) {
1715
+ // Right-click opens the actions dialog
1716
+ useStore.setState({ showActionsDialog: true })
1717
+ } else if (props.actions) {
1712
1718
  useStore.setState({ shouldAutoExecuteFirstAction: true })
1713
1719
  }
1714
1720
  }
@@ -2240,9 +2246,9 @@ function EmptyViewContent(props: EmptyViewProps): any {
2240
2246
  useKeyboard((evt) => {
2241
2247
  if (!inFocus) return
2242
2248
 
2243
- // Handle Ctrl+K to show actions dialog via portal
2249
+ // Handle Ctrl+K / Cmd+K to show actions dialog via portal
2244
2250
  // Always open — built-in actions (Change Theme, etc.) are always available
2245
- if (evt.name === 'k' && evt.ctrl) {
2251
+ if (evt.name === 'k' && (evt.ctrl || evt.super)) {
2246
2252
  useStore.setState({ showActionsDialog: true })
2247
2253
  return
2248
2254
  }
@@ -87,10 +87,10 @@ test('many columns (20) clips with overflow hidden', async () => {
87
87
 
88
88
  > Search...
89
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 │ ███ ███ ███ ███ ███ ███ ██
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
94
  Many Series (8) Legend overflow test │ ███ ███ ███ ███ ███ ███ ███ ███ ██
95
95
  Long Labels Labels wider than bar co │ ███ ███ ███ ███ ███ ███ ███ ███ ██
96
96
  Week 1 vs Week 2 Two graphs in a Row │ ███ ███ ███ ███ ███ ███ ███ ███ ██
@@ -35,7 +35,7 @@ test('initial render shows bar chart for Monthly Budget', async () => {
35
35
  ›Monthly Budget Spent / Remaining / Savings │ ┌Spent: 78.6%┐
36
36
  Disk Usage System / Apps / Media / Free │
37
37
  Investment Portfolio Stocks / Bonds / Cash / C │
38
- CPU Time User / System / IO Wait / Idle │ ───────────────────────────────────────────
38
+ CPU Time User / System / IO Wait / Idle │ ────────────────────────────────────────────
39
39
  Revenue by Product 6 product lines │
40
40
  A/B Test Split Control vs Variant (50/50) │ Total: $6,174
41
41
  Storage Full 100% used │
@@ -46,15 +46,15 @@ test('initial render shows bar chart for Monthly Budget', async () => {
46
46
  Stress Test (20 items) Many small equal segmen │
47
47
 
48
48
 
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
49
  ↵ open detail ↑↓ navigate ^k actions │
57
50
 
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
58
  "
59
59
  `)
60
60
  expect(text).toContain('Monthly Budget')
@@ -40,13 +40,13 @@ test('side detail shows two graphs in a row', async () => {
40
40
  Sparse Data (Zeros) Filled vs Striped with zer │ climbing.
41
41
 
42
42
  │ 100│ ⡀ 100│
43
- │ │ ⣠ ⢠⣾⣷⡀ │ ▄▄▀▀
44
- │ 67│ ⣰⣿⣧ ⢀⣿⣿⣿⣇ 67│ ▄▄▀▀▀▀▀▀▀
45
- │ │ ⢠⣷⣿⣿⣿⣆ ⣾⣿⣿⣿⣿⡄ │ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀
46
- │ │ ⢀⣿⣿⣿⣿⣿⣿⣆⣸⣿⣿⣿⣿⣿⣿⣄ │▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
47
- │ 33│⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ 33│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
48
- │ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
49
- │ 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
43
+ │ │ ⣠ ⢠⣾⣷⡀ │ ▖▖▌▌
44
+ │ 67│ ⣰⣿⣧ ⢀⣿⣿⣿⣇ 67│ ▖▖▌▌▌▌▌▌▌
45
+ │ │ ⢠⣷⣿⣿⣿⣆ ⣾⣿⣿⣿⣿⡄ │ ▖▖▌▌▌▌▌▌▌▌▌▌▌▌
46
+ │ │ ⢀⣿⣿⣿⣿⣿⣿⣆⣸⣿⣿⣿⣿⣿⣿⣄ │▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
47
+ │ 33│⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ 33│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
48
+ │ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
49
+ │ 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
50
50
  │ 0h 6h 12h 18h24h 0h 6h 12h 18h24h
51
51
 
52
52
  │ ────────────────────────────────────────────
@@ -96,17 +96,17 @@ test('enter pushes full detail with two graphs', async () => {
96
96
  Filled chart (right) shows memory steadily climbing.
97
97
 
98
98
  100│ 100│
99
- │ ⢀⣠⣴⡄ │
100
- │ ⣠⣦ ⣠⣿⣿⣿⣿⣦ │ ▄▄▄▄▄▀▀▀▀▀
101
- │ ⢠⣾⣿⣿⣷⡄ ⢀⣼⣿⣿⣿⣿⣿⣿⣷⡀ │ ▄▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
102
- 67│ ⢀⡀ ⣰⣿⣿⣿⣿⣿⣿⡄ ⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀ 67│ ▄▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
103
- │ ⢠⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⡄ ⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄ │ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
104
- │ ⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀ ⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⡀ │ ▄▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
105
- 33│ ⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄ 33│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
106
- │⣀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷ │▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
107
- │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
108
- │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
109
- 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
99
+ │ ⢀⣠⣴⡄ │
100
+ │ ⣠⣦ ⣠⣿⣿⣿⣿⣦ │ ▖▖▖▖▖▌▌▌▌▌
101
+ │ ⢠⣾⣿⣿⣷⡄ ⢀⣼⣿⣿⣿⣿⣿⣿⣷⡀ │ ▖▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
102
+ 67│ ⢀⡀ ⣰⣿⣿⣿⣿⣿⣿⡄ ⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀ 67│ ▖▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
103
+ │ ⢠⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⡄ ⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄ │ ▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
104
+ │ ⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀ ⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⡀ │ ▖▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
105
+ 33│ ⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄ 33│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
106
+ │⣀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷ │▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
107
+ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
108
+ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
109
+ 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
110
110
 
111
111
 
112
112
  esc go back ^k actions ↵ Go Back powered by termcast.app
@@ -159,13 +159,13 @@ test('esc returns from detail to list', async () => {
159
159
  Sparse Data (Zeros) Filled vs Striped with zer │ climbing.
160
160
 
161
161
  │ 100│ ⡀ 100│
162
- │ │ ⣠ ⢠⣾⣷⡀ │ ▄▄▀▀
163
- │ 67│ ⣰⣿⣧ ⢀⣿⣿⣿⣇ 67│ ▄▄▀▀▀▀▀▀▀
164
- │ │ ⢠⣷⣿⣿⣿⣆ ⣾⣿⣿⣿⣿⡄ │ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀
165
- │ │ ⢀⣿⣿⣿⣿⣿⣿⣆⣸⣿⣿⣿⣿⣿⣿⣄ │▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
166
- │ 33│⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ 33│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
167
- │ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
168
- │ 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
162
+ │ │ ⣠ ⢠⣾⣷⡀ │ ▖▖▌▌
163
+ │ 67│ ⣰⣿⣧ ⢀⣿⣿⣿⣇ 67│ ▖▖▌▌▌▌▌▌▌
164
+ │ │ ⢠⣷⣿⣿⣿⣆ ⣾⣿⣿⣿⣿⡄ │ ▖▖▌▌▌▌▌▌▌▌▌▌▌▌
165
+ │ │ ⢀⣿⣿⣿⣿⣿⣿⣆⣸⣿⣿⣿⣿⣿⣿⣄ │▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
166
+ │ 33│⣀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧ 33│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
167
+ │ │⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ │▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
168
+ │ 0│⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 0│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
169
169
  │ 0h 6h 12h 18h24h 0h 6h 12h 18h24h
170
170
 
171
171
  │ ────────────────────────────────────────────
@@ -215,14 +215,14 @@ test('sparse data with zeros shows baseline', async () => {
215
215
  Mixed Variants Area left, Striped right │ baseline line so bars are visible even at
216
216
  ›Sparse Data (Zeros) Filled vs Striped with zer │ zero.
217
217
 
218
- │ 100│ 100│
219
- │ │ ▄▀ ▄▀
220
- │ 67│ ▀▀ 67│ ▀▀
221
- │ │ ▀▀ ▄▀ ▀▀▀▀ ▄▀ ▀▀
222
- │ │ ▀▀ ▀▀ ▀▀▄▀▀ ▀▀ ▀▀▄
223
- │ 33│ ▀▀▀ ▀▀▄▀▀▀▀ 33│ ▀▀▀ ▀▀▄ ▀▀▀
224
- │ │ ▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ▀▀▀
225
- │ 0│▁▀▀▀▀▀▀▀▁▀▀▀▀▀▀▀▀▁ 0│▁▀▀▀▀▀▀▀▀▀▀▀▁▀▀▀▁
218
+ │ 100│ 100│
219
+ │ │ ▖▌ ▖▌
220
+ │ 67│ ▌▌ 67│ ▌▌
221
+ │ │ ▌▌ ▖▌ ▌▌▌▌ ▖▌ ▌▌
222
+ │ │ ▌▌ ▌▌ ▌▌▖▌▌ ▌▌ ▌▌▖
223
+ │ 33│ ▌▌▌ ▌▌▖▌▌▌▌ 33│ ▌▌▌ ▌▌▖ ▌▌▌
224
+ │ │ ▌▌▌▌▌▌ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ ▌▌▌
225
+ │ 0│▖▌▌▌▌▌▌▌▖▌▌▌▌▌▌▌▌▖ 0│▖▌▌▌▌▌▌▌▌▌▌▌▖▌▌▌▖
226
226
  │ 0h 6h 12h 18h24h 0h 6h 12h 18h24h
227
227
 
228
228
  │ ────────────────────────────────────────────
@@ -273,14 +273,14 @@ test('navigate to striped pair', async () => {
273
273
  │ - Expenses: $8k to $45k
274
274
 
275
275
 
276
- │ 78│ 47│
277
- │ │ ▄▀▀▀▄▄▀▀▀
278
- │ 54│ ▄▀▀▀▀▀ 33│ ▄▄▀▀▀▀▀
279
- │ │ ▄▄▀▀▀▀▀▀▀▄▀▀▀▀▀▀▀▀
280
- │ │ ▀▀▀▀▀▀▀▀▀▀▄▄▀▀▀▀▀▀▀▀▀▀
281
- │ 31│ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀ 20│ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀
282
- │ │ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
283
- │ 7│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ 6│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
276
+ │ 78│ 47│
277
+ │ │ ▖▌▌▌▖▖▌▌▌
278
+ │ 54│ ▖▌▌▌▌▌ 33│ ▖▖▌▌▌▌▌
279
+ │ │ ▖▖▌▌▌▌▌▌▌▖▌▌▌▌▌▌▌▌
280
+ │ │ ▌▌▌▌▌▌▌▌▌▌▖▖▌▌▌▌▌▌▌▌▌▌
281
+ │ 31│ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌ 20│ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌
282
+ │ │ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
283
+ │ 7│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌ 6│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
284
284
  │ Jan Apr Jul Oct Jan Apr Jul Oct
285
285
 
286
286
  │ ───────────────────────────────────────────
@@ -291,5 +291,5 @@ test('navigate to striped pair', async () => {
291
291
  `)
292
292
 
293
293
  expect(text).toContain('›Revenue vs Expenses')
294
- expect(text).toMatch(/[▄▀]/)
294
+ expect(text).toMatch(/[▌▘▖]/)
295
295
  }, 30000)
@@ -93,18 +93,18 @@ test('filled style renders block characters', async () => {
93
93
  Filled - Yellow CPU High contrast on │ Q2: $25k → Q3: $50k (+100%)
94
94
  Filled - Magenta Waves Smooth curve │ Q3: $50k → Q4: $75k (+50%)
95
95
  Striped - Purple/Orange Warm alterna │
96
- Striped - Blue/Red High contrast str │ 78│
97
- Striped - Theme Default primary + ac │ │ ▄▀▄▀▀
98
- Striped - Green/Yellow Nature-inspir │ │ ▄▄▄▀▀▀▀▀▀
99
- Striped - Red/Magenta Warm gradient │ 54│ ▄▀▀▀▀▀▀▀▀▀▀
100
- │ │ ▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀
101
- │ │ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
102
- ↵ open detail ↑↓ navigate ^k act │ 31│ ▄▀▀▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
96
+ Striped - Blue/Red High contrast str │ 78│
97
+ Striped - Theme Default primary + ac │ │ ▖▌▖▌▌
98
+ Striped - Green/Yellow Nature-inspir │ │ ▖▖▖▌▌▌▌▌▌
99
+ Striped - Red/Magenta Warm gradient │ 54│ ▖▌▌▌▌▌▌▌▌▌▌
100
+ │ │ ▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌
101
+ │ │ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
102
+ ↵ open detail ↑↓ navigate ^k act │ 31│ ▖▌▌▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
103
103
 
104
104
  "
105
105
  `)
106
106
 
107
- expect(text).toMatch(/[▄▀]/)
107
+ expect(text).toMatch(/[▌▘▖]/)
108
108
  expect(text).toContain('›Filled - Red')
109
109
  }, 30000)
110
110
 
@@ -136,16 +136,16 @@ test('striped style renders alternating columns', async () => {
136
136
 
137
137
  > Search...
138
138
 
139
- Area - Stock Price Orange braille do │ 211│
140
- Area - Multi Series CPU + Memory ove │ │ ▄▄▀▀
141
- Area - Waves Purple + Magenta sine/c │ │ ▄▄▄▀▀▀▀▀
142
- Area - Blue Revenue Single series, a │ 189│ ▄▄▀▄▀▀▀▀▀▀▀▀▀
143
- Filled - Red Revenue Solid block gro │ │ ▄▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀
144
- Filled - Green Temp Daily temperatur │ │ ▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
145
- Filled - Yellow CPU High contrast on │ 167│ ▄▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
146
- Filled - Magenta Waves Smooth curve │ │ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
147
- ›Striped - Purple/Orange Warm alterna │ │▄▀▄▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
148
- Striped - Blue/Red High contrast str │ 145│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
139
+ Area - Stock Price Orange braille do │ 211│
140
+ Area - Multi Series CPU + Memory ove │ │ ▖▖▌▌
141
+ Area - Waves Purple + Magenta sine/c │ │ ▖▖▖▌▌▌▌▌
142
+ Area - Blue Revenue Single series, a │ 189│ ▖▖▌▖▌▌▌▌▌▌▌▌▌
143
+ Filled - Red Revenue Solid block gro │ │ ▖▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌
144
+ Filled - Green Temp Daily temperatur │ │ ▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
145
+ Filled - Yellow CPU High contrast on │ 167│ ▖▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
146
+ Filled - Magenta Waves Smooth curve │ │ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
147
+ ›Striped - Purple/Orange Warm alterna │ │▖▌▖▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
148
+ Striped - Blue/Red High contrast str │ 145│▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌
149
149
  Striped - Theme Default primary + ac │ 1 5 10 15 20
150
150
  Striped - Green/Yellow Nature-inspir │
151
151
  Striped - Red/Magenta Warm gradient │ ─────────────────────────────────
@@ -156,7 +156,7 @@ test('striped style renders alternating columns', async () => {
156
156
  "
157
157
  `)
158
158
 
159
- expect(text).toMatch(/[▄▀]/)
159
+ expect(text).toMatch(/[▌▘▖]/)
160
160
  expect(text).toContain('›Striped - Purple')
161
161
  }, 30000)
162
162
 
@@ -43,37 +43,37 @@ test('renders calendar heatmaps with various color combinations', async () => {
43
43
  terminal width are truncated from the left.
44
44
 
45
45
  May Jun Jul Aug Sep Oct Nov
46
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
47
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
48
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
49
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
50
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
51
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Fri
52
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
53
- Less ◼ ◼ More
46
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
47
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
48
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
49
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
50
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
51
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Fri
52
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
53
+ Less ◼ ◼ More
54
54
 
55
55
  Journal — summer + winter entries in green, with a fall gap between the two
56
56
  ranges.
57
57
 
58
58
  Jun Jul Aug Sep Jan Feb
59
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
60
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
61
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
62
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
63
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
64
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼Fri
65
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
66
- Less ◼ ◼ More
59
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
60
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
61
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
62
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
63
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
64
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Fri
65
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
66
+ Less ◼ ◼ More
67
67
 
68
68
  Recent activity — last 150 days in red, showing the sine-wave pattern clearly.
69
69
 
70
70
  Se Oct Nov Dec Jan Feb
71
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
72
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
73
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
74
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
75
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
76
- ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Fri
71
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
72
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Mon
73
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
74
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Wed
75
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼
76
+ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ ◼ Fri
77
77
 
78
78
 
79
79
  esc go back ^k actions powered by termcast.app