gloomberb 0.9.4 → 0.9.5
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/package.json +3 -2
- package/patches/@opentui%2Fcore@0.3.2.patch +231 -29
- package/patches/react-reconciler@0.33.0.patch +10 -0
- package/src/cli/entry.ts +8 -1
- package/src/cli/native-smoke.ts +5 -0
- package/src/components/chart/native/bitmap-support.test.ts +27 -0
- package/src/components/chart/native/bitmap-support.ts +55 -0
- package/src/components/chart/native/kitty/index.test.ts +47 -0
- package/src/components/chart/native/surface/visibility.ts +8 -1
- package/src/components/chart/static/chart/bitmap.ts +16 -9
- package/src/components/command-bar/list/view.tsx +1 -1
- package/src/components/command-bar/theme-picker.tsx +1 -1
- package/src/components/data-table/view.tsx +0 -12
- package/src/components/layout/floating-pane.tsx +3 -3
- package/src/components/layout/pane/header.tsx +5 -0
- package/src/components/layout/pane/index.tsx +3 -3
- package/src/components/layout/shell/action-menu-overlay.tsx +1 -1
- package/src/components/layout/shell/cursor-occlusion.ts +9 -1
- package/src/components/layout/shell/index.tsx +8 -1
- package/src/components/layout/shell/pane/layers.tsx +2 -2
- package/src/components/layout/status-bar.tsx +5 -5
- package/src/components/pane-settings-dialog/desktop.tsx +1 -1
- package/src/components/price-performance.tsx +1 -1
- package/src/components/price-sparkline/view.tsx +15 -14
- package/src/components/speedometer-gauge/terminal.tsx +18 -15
- package/src/components/table-view-shared.tsx +0 -10
- package/src/components/ticker/list-table-view.tsx +1 -7
- package/src/components/ticker/list-table.test.tsx +0 -4
- package/src/components/ui/data-table/opentui/index.tsx +4 -10
- package/src/components/ui/data-table/types.ts +6 -4
- package/src/components/ui/list-view.tsx +1 -1
- package/src/components/ui/tabs.tsx +1 -2
- package/src/components/ui/ui.test.tsx +0 -9
- package/src/plugins/builtin/account-management/form-components.tsx +2 -2
- package/src/plugins/builtin/alerts/pane.tsx +1 -1
- package/src/plugins/builtin/buildout/cells.tsx +1 -1
- package/src/plugins/builtin/buildout/pane/index.tsx +1 -1
- package/src/plugins/builtin/chat/message/desktop.tsx +1 -1
- package/src/plugins/builtin/chat/message/inline-tokens.tsx +1 -1
- package/src/plugins/builtin/chat/message/terminal.tsx +2 -2
- package/src/plugins/builtin/chat/sidebar.tsx +1 -1
- package/src/plugins/builtin/chat/status-widget.tsx +1 -1
- package/src/plugins/builtin/cloud/auth-actions.tsx +2 -2
- package/src/plugins/builtin/correlation/matrix/symbol-cell.tsx +1 -1
- package/src/plugins/builtin/debug/index.tsx +3 -4
- package/src/plugins/builtin/help/components.tsx +1 -1
- package/src/plugins/builtin/holders/treemap.tsx +1 -1
- package/src/plugins/builtin/options/table.ts +5 -5
- package/src/plugins/ibkr/trade/ticket-panel.tsx +1 -1
- package/src/renderers/electrobun/view/data-table/index.tsx +0 -8
- package/src/renderers/electrobun/view/data-table/row.tsx +2 -12
- package/src/renderers/electrobun/view/host/box.tsx +6 -1
- package/src/renderers/electrobun/view/host/style.ts +1 -0
- package/src/renderers/electrobun/view/styles.css +7 -0
- package/src/renderers/opentui/native-smoke.ts +1 -0
- package/src/version.ts +1 -1
|
@@ -73,8 +73,6 @@ export interface DataTableViewProps<
|
|
|
73
73
|
| "scrollRef"
|
|
74
74
|
| "syncHeaderScroll"
|
|
75
75
|
| "onBodyScrollActivity"
|
|
76
|
-
| "hoveredIdx"
|
|
77
|
-
| "setHoveredIdx"
|
|
78
76
|
| "isSelected"
|
|
79
77
|
| "onSelect"
|
|
80
78
|
| "onActivate"
|
|
@@ -97,8 +95,6 @@ export interface DataTableViewProps<
|
|
|
97
95
|
scrollRef?: RefObject<ScrollBoxRenderable | null>;
|
|
98
96
|
syncHeaderScroll?: () => void;
|
|
99
97
|
onBodyScrollActivity?: () => void;
|
|
100
|
-
hoveredIdx?: number | null;
|
|
101
|
-
setHoveredIdx?: (index: number | null) => void;
|
|
102
98
|
keyboardNavigation?: boolean;
|
|
103
99
|
onRootKeyDown?: (
|
|
104
100
|
event: DataTableKeyEvent,
|
|
@@ -125,8 +121,6 @@ export function DataTableView<
|
|
|
125
121
|
scrollRef,
|
|
126
122
|
syncHeaderScroll,
|
|
127
123
|
onBodyScrollActivity,
|
|
128
|
-
hoveredIdx,
|
|
129
|
-
setHoveredIdx,
|
|
130
124
|
keyboardNavigation = true,
|
|
131
125
|
onRootKeyDown,
|
|
132
126
|
resetScrollKey,
|
|
@@ -137,15 +131,11 @@ export function DataTableView<
|
|
|
137
131
|
const {
|
|
138
132
|
effectiveHeaderScrollRef,
|
|
139
133
|
effectiveScrollRef,
|
|
140
|
-
effectiveHoveredIdx,
|
|
141
|
-
effectiveSetHoveredIdx,
|
|
142
134
|
effectiveSyncHeaderScroll,
|
|
143
135
|
} = useTableViewState({
|
|
144
136
|
headerScrollRef,
|
|
145
137
|
scrollRef,
|
|
146
138
|
syncHeaderScroll,
|
|
147
|
-
hoveredIdx,
|
|
148
|
-
setHoveredIdx,
|
|
149
139
|
});
|
|
150
140
|
const [cursorIndex, setCursorIndex] = useState<number | null>(null);
|
|
151
141
|
const pendingCommitRef = useRef(false);
|
|
@@ -532,8 +522,6 @@ export function DataTableView<
|
|
|
532
522
|
scrollRef={effectiveScrollRef}
|
|
533
523
|
syncHeaderScroll={effectiveSyncHeaderScroll}
|
|
534
524
|
onBodyScrollActivity={handleBodyScrollActivity}
|
|
535
|
-
hoveredIdx={effectiveHoveredIdx}
|
|
536
|
-
setHoveredIdx={effectiveSetHoveredIdx}
|
|
537
525
|
scrollToIndex={effectiveScrollToIndex}
|
|
538
526
|
scrollToIndexVersion={scrollToIndexVersion + selectionScrollVersion}
|
|
539
527
|
isSelected={isItemSelected}
|
|
@@ -18,7 +18,7 @@ interface FloatingPaneWrapperProps {
|
|
|
18
18
|
windowModeSelected?: boolean;
|
|
19
19
|
showActions?: boolean;
|
|
20
20
|
onMouseDown?: (event: any) => void;
|
|
21
|
-
|
|
21
|
+
onHeaderMouseMove?: (event: any) => void;
|
|
22
22
|
onHeaderMouseDown?: (event: any) => void;
|
|
23
23
|
onHeaderMouseDrag?: (event: any) => void;
|
|
24
24
|
onHeaderMouseDragEnd?: (event: any) => void;
|
|
@@ -63,7 +63,7 @@ export function FloatingPaneWrapper({
|
|
|
63
63
|
windowModeSelected = false,
|
|
64
64
|
showActions = false,
|
|
65
65
|
onMouseDown,
|
|
66
|
-
|
|
66
|
+
onHeaderMouseMove,
|
|
67
67
|
onHeaderMouseDown,
|
|
68
68
|
onHeaderMouseDrag,
|
|
69
69
|
onHeaderMouseDragEnd,
|
|
@@ -104,7 +104,6 @@ export function FloatingPaneWrapper({
|
|
|
104
104
|
showBorderColor: true,
|
|
105
105
|
})}
|
|
106
106
|
onMouseDown={onMouseDown}
|
|
107
|
-
onMouseMove={onMouseMove}
|
|
108
107
|
>
|
|
109
108
|
<PaneHeader
|
|
110
109
|
title={title}
|
|
@@ -113,6 +112,7 @@ export function FloatingPaneWrapper({
|
|
|
113
112
|
windowModeSelected={windowModeSelected}
|
|
114
113
|
floating
|
|
115
114
|
showActions={showActions}
|
|
115
|
+
onHeaderMouseMove={onHeaderMouseMove}
|
|
116
116
|
onHeaderMouseDown={onHeaderMouseDown}
|
|
117
117
|
onHeaderMouseDrag={onHeaderMouseDrag}
|
|
118
118
|
onHeaderMouseDragEnd={onHeaderMouseDragEnd}
|
|
@@ -14,6 +14,7 @@ interface PaneHeaderProps {
|
|
|
14
14
|
windowModeSelected?: boolean;
|
|
15
15
|
floating?: boolean;
|
|
16
16
|
showActions?: boolean;
|
|
17
|
+
onHeaderMouseMove?: (event: any) => void;
|
|
17
18
|
onHeaderMouseDown?: (event: any) => void;
|
|
18
19
|
onHeaderMouseDrag?: (event: any) => void;
|
|
19
20
|
onHeaderMouseDragEnd?: (event: any) => void;
|
|
@@ -111,6 +112,7 @@ export function PaneHeader({
|
|
|
111
112
|
windowModeSelected = false,
|
|
112
113
|
floating = false,
|
|
113
114
|
showActions = false,
|
|
115
|
+
onHeaderMouseMove,
|
|
114
116
|
onHeaderMouseDown,
|
|
115
117
|
onHeaderMouseDrag,
|
|
116
118
|
onHeaderMouseDragEnd,
|
|
@@ -143,6 +145,7 @@ export function PaneHeader({
|
|
|
143
145
|
data-focused={focused ? "true" : "false"}
|
|
144
146
|
data-window-mode-selected={windowModeSelected ? "true" : "false"}
|
|
145
147
|
onMouseDown={onHeaderMouseDown}
|
|
148
|
+
onMouseMove={onHeaderMouseMove}
|
|
146
149
|
onMouseDrag={onHeaderMouseDrag}
|
|
147
150
|
onMouseDragEnd={onHeaderMouseDragEnd}
|
|
148
151
|
onContextMenu={onHeaderContextMenu}
|
|
@@ -226,6 +229,7 @@ export function PaneHeader({
|
|
|
226
229
|
backgroundColor={backgroundColor}
|
|
227
230
|
flexDirection="row"
|
|
228
231
|
onMouseDown={handleTerminalHeaderMouseDown}
|
|
232
|
+
onMouseMove={onHeaderMouseMove}
|
|
229
233
|
onMouseDrag={onHeaderMouseDrag}
|
|
230
234
|
onMouseDragEnd={onHeaderMouseDragEnd}
|
|
231
235
|
>
|
|
@@ -263,6 +267,7 @@ export function PaneHeader({
|
|
|
263
267
|
backgroundColor={backgroundColor}
|
|
264
268
|
flexDirection="row"
|
|
265
269
|
onMouseDown={handleTerminalHeaderMouseDown}
|
|
270
|
+
onMouseMove={onHeaderMouseMove}
|
|
266
271
|
onMouseDrag={onHeaderMouseDrag}
|
|
267
272
|
onMouseDragEnd={onHeaderMouseDragEnd}
|
|
268
273
|
>
|
|
@@ -16,7 +16,7 @@ interface PaneWrapperProps {
|
|
|
16
16
|
flexGrow?: number;
|
|
17
17
|
showActions?: boolean;
|
|
18
18
|
onMouseDown?: (event: any) => void;
|
|
19
|
-
|
|
19
|
+
onHeaderMouseMove?: (event: any) => void;
|
|
20
20
|
onHeaderMouseDown?: (event: any) => void;
|
|
21
21
|
onHeaderMouseDrag?: (event: any) => void;
|
|
22
22
|
onHeaderMouseDragEnd?: (event: any) => void;
|
|
@@ -36,7 +36,7 @@ export function PaneWrapper({
|
|
|
36
36
|
flexGrow,
|
|
37
37
|
showActions = false,
|
|
38
38
|
onMouseDown,
|
|
39
|
-
|
|
39
|
+
onHeaderMouseMove,
|
|
40
40
|
onHeaderMouseDown,
|
|
41
41
|
onHeaderMouseDrag,
|
|
42
42
|
onHeaderMouseDragEnd,
|
|
@@ -76,7 +76,6 @@ export function PaneWrapper({
|
|
|
76
76
|
showBorderColor: true,
|
|
77
77
|
})}
|
|
78
78
|
onMouseDown={onMouseDown}
|
|
79
|
-
onMouseMove={onMouseMove}
|
|
80
79
|
>
|
|
81
80
|
{title && (
|
|
82
81
|
<PaneHeader
|
|
@@ -85,6 +84,7 @@ export function PaneWrapper({
|
|
|
85
84
|
focused={focused}
|
|
86
85
|
windowModeSelected={windowModeSelected}
|
|
87
86
|
showActions={showActions}
|
|
87
|
+
onHeaderMouseMove={onHeaderMouseMove}
|
|
88
88
|
onHeaderMouseDown={onHeaderMouseDown}
|
|
89
89
|
onHeaderMouseDrag={onHeaderMouseDrag}
|
|
90
90
|
onHeaderMouseDragEnd={onHeaderMouseDragEnd}
|
|
@@ -52,7 +52,7 @@ export function ShellActionMenuOverlay({
|
|
|
52
52
|
height={1}
|
|
53
53
|
width={innerWidth}
|
|
54
54
|
backgroundColor={hovered ? colors.selected : colors.panel}
|
|
55
|
-
|
|
55
|
+
onMouseOver={() => onHoverItem(item.id)}
|
|
56
56
|
onMouseDown={(mouseEvent: any) => {
|
|
57
57
|
mouseEvent.stopPropagation();
|
|
58
58
|
mouseEvent.preventDefault();
|
|
@@ -23,6 +23,8 @@ interface ResolveShellCursorOcclusionRectsOptions {
|
|
|
23
23
|
width: number;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
const MAX_RENDERABLE_ANCESTOR_DEPTH = 256;
|
|
27
|
+
|
|
26
28
|
export function resolveShellCursorOcclusionRects({
|
|
27
29
|
contentHeight,
|
|
28
30
|
dragFloatingRect,
|
|
@@ -102,7 +104,13 @@ function readRenderableBounds(renderable: unknown): LayoutBounds | null {
|
|
|
102
104
|
|
|
103
105
|
function readRenderablePaneId(renderable: unknown): string | null {
|
|
104
106
|
let current = renderable;
|
|
105
|
-
|
|
107
|
+
const seen = new Set<object>();
|
|
108
|
+
let depth = 0;
|
|
109
|
+
|
|
110
|
+
while (current && typeof current === "object" && !seen.has(current)) {
|
|
111
|
+
if (depth >= MAX_RENDERABLE_ANCESTOR_DEPTH) return null;
|
|
112
|
+
seen.add(current);
|
|
113
|
+
depth += 1;
|
|
106
114
|
const record = current as Record<string, unknown>;
|
|
107
115
|
const paneId = record["data-gloom-pane-id"];
|
|
108
116
|
if (typeof paneId === "string") return paneId;
|
|
@@ -525,7 +525,14 @@ export function Shell({
|
|
|
525
525
|
height={nativePaneChrome ? undefined : contentHeight}
|
|
526
526
|
position={nativePaneChrome ? "relative" : undefined}
|
|
527
527
|
overflow="hidden"
|
|
528
|
-
{...(!nativePaneChrome
|
|
528
|
+
{...(!nativePaneChrome
|
|
529
|
+
? {
|
|
530
|
+
onMouseDown: handleMouse,
|
|
531
|
+
onMouseDrag: handleMouse,
|
|
532
|
+
onMouseDragEnd: handleMouse,
|
|
533
|
+
onMouseUp: handleMouse,
|
|
534
|
+
}
|
|
535
|
+
: {})}
|
|
529
536
|
>
|
|
530
537
|
<Box
|
|
531
538
|
position="absolute"
|
|
@@ -132,7 +132,7 @@ export function ShellPaneLayers({
|
|
|
132
132
|
windowModeSelected={windowModeSelected}
|
|
133
133
|
footer={footer}
|
|
134
134
|
onMouseDown={nativePaneChrome ? (event) => handleNativePaneMouseDown(leaf.instanceId, event) : undefined}
|
|
135
|
-
|
|
135
|
+
onHeaderMouseMove={() => setHoveredPaneIfChanged(leaf.instanceId)}
|
|
136
136
|
onHeaderMouseDown={nativePaneChrome && !transientFocusActive ? (event) => startNativeDockedDrag(leaf.instanceId, rect, event) : undefined}
|
|
137
137
|
onHeaderMouseDrag={nativePaneChrome && !transientFocusActive ? handleNativeDrag : undefined}
|
|
138
138
|
onHeaderMouseDragEnd={nativePaneChrome && !transientFocusActive ? handleNativeDrag : undefined}
|
|
@@ -192,7 +192,7 @@ export function ShellPaneLayers({
|
|
|
192
192
|
showActions={showActions}
|
|
193
193
|
footer={footer}
|
|
194
194
|
onMouseDown={nativePaneChrome ? (event) => handleNativePaneMouseDown(pane.instance.instanceId, event) : undefined}
|
|
195
|
-
|
|
195
|
+
onHeaderMouseMove={() => setHoveredPaneIfChanged(pane.instance.instanceId)}
|
|
196
196
|
onHeaderMouseDown={nativePaneChrome ? (event) => startNativeFloatingDrag(pane.instance.instanceId, preview, event) : undefined}
|
|
197
197
|
onHeaderMouseDrag={nativePaneChrome ? handleNativeDrag : undefined}
|
|
198
198
|
onHeaderMouseDragEnd={nativePaneChrome ? handleNativeDrag : undefined}
|
|
@@ -364,7 +364,7 @@ function CommandBarHint({
|
|
|
364
364
|
<Text
|
|
365
365
|
fg={hovered ? colors.text : colors.textDim}
|
|
366
366
|
{...(!nativePaneChrome ? { bg: hovered ? hoverBg() : undefined } : {})}
|
|
367
|
-
|
|
367
|
+
onMouseOver={() => setHoveredControl((current) => (current === "command-bar" ? current : "command-bar"))}
|
|
368
368
|
onMouseDown={openCommandBar}
|
|
369
369
|
{...(nativePaneChrome ? { "data-gloom-interactive": "true" } : {})}
|
|
370
370
|
>
|
|
@@ -385,7 +385,7 @@ function NativeGridlockTip({
|
|
|
385
385
|
<Text
|
|
386
386
|
fg={hoveredControl === "gridlock-tip" ? colors.textBright : colors.borderFocused}
|
|
387
387
|
attributes={TextAttributes.BOLD}
|
|
388
|
-
|
|
388
|
+
onMouseOver={() => setHoveredControl((current) => (current === "gridlock-tip" ? current : "gridlock-tip"))}
|
|
389
389
|
onMouseDown={handleGridlockTip}
|
|
390
390
|
data-gloom-interactive="true"
|
|
391
391
|
>
|
|
@@ -393,7 +393,7 @@ function NativeGridlockTip({
|
|
|
393
393
|
</Text>
|
|
394
394
|
<Text
|
|
395
395
|
fg={hoveredControl === "gridlock-tip-dismiss" ? colors.text : colors.textDim}
|
|
396
|
-
|
|
396
|
+
onMouseOver={() => setHoveredControl((current) => (current === "gridlock-tip-dismiss" ? current : "gridlock-tip-dismiss"))}
|
|
397
397
|
onMouseDown={dismissGridlockTip}
|
|
398
398
|
data-gloom-interactive="true"
|
|
399
399
|
>
|
|
@@ -415,14 +415,14 @@ function TerminalGridlockTip({
|
|
|
415
415
|
<Box width={1} />
|
|
416
416
|
<Box
|
|
417
417
|
backgroundColor={hoveredControl === "gridlock-tip" ? hoverBg() : colors.header}
|
|
418
|
-
|
|
418
|
+
onMouseOver={() => setHoveredControl((current) => (current === "gridlock-tip" ? current : "gridlock-tip"))}
|
|
419
419
|
onMouseDown={handleGridlockTip}
|
|
420
420
|
>
|
|
421
421
|
<Text fg={colors.headerText}> Gridlock All </Text>
|
|
422
422
|
</Box>
|
|
423
423
|
<Text
|
|
424
424
|
fg={hoveredControl === "gridlock-tip-dismiss" ? colors.text : colors.textDim}
|
|
425
|
-
|
|
425
|
+
onMouseOver={() => setHoveredControl((current) => (current === "gridlock-tip-dismiss" ? current : "gridlock-tip-dismiss"))}
|
|
426
426
|
onMouseDown={dismissGridlockTip}
|
|
427
427
|
>
|
|
428
428
|
{" x"}
|
|
@@ -183,7 +183,7 @@ function DesktopSettingsRow({
|
|
|
183
183
|
flexDirection="column"
|
|
184
184
|
minHeight={field.description ? undefined : 2}
|
|
185
185
|
backgroundColor={hovered || selected ? desktopHoverSurface() : "transparent"}
|
|
186
|
-
|
|
186
|
+
onMouseOver={onHover}
|
|
187
187
|
onMouseDown={field.type === "select" ? undefined : (event: any) => {
|
|
188
188
|
event.stopPropagation?.();
|
|
189
189
|
event.preventDefault?.();
|
|
@@ -157,7 +157,7 @@ export function PriceReturnTable({
|
|
|
157
157
|
height={1}
|
|
158
158
|
width={width}
|
|
159
159
|
backgroundColor={row.selected ? blendHex(colors.panel, colors.borderFocused, 0.18) : colors.panel}
|
|
160
|
-
|
|
160
|
+
onMouseOver={() => onSelectSymbol(row.symbol)}
|
|
161
161
|
onMouseDown={(event: any) => {
|
|
162
162
|
onFocusInteraction?.(event);
|
|
163
163
|
onSelectSymbol(row.symbol);
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { colors } from "../../theme/colors";
|
|
11
11
|
import { useThemeColors } from "../../theme/theme-context";
|
|
12
12
|
import type { PricePoint } from "../../types/financials";
|
|
13
|
-
import {
|
|
13
|
+
import { resolveNativeBitmapSize, shouldRenderNativeBitmap } from "../chart/native/bitmap-support";
|
|
14
14
|
import { renderSparklineBitmap } from "./bitmap";
|
|
15
15
|
import {
|
|
16
16
|
buildSamples,
|
|
@@ -90,22 +90,21 @@ function TerminalPriceSparkline({
|
|
|
90
90
|
const { nativeCharts, cellWidthPx = 8, cellHeightPx = 18, pixelRatio = 1 } = useUiCapabilities();
|
|
91
91
|
const nativeRenderer = useNativeRenderer();
|
|
92
92
|
const rendererResolution = nativeRenderer.resolution;
|
|
93
|
+
const rendererCapabilities = nativeRenderer.capabilities;
|
|
93
94
|
const rendererTerminalWidth = nativeRenderer.terminalWidth;
|
|
94
95
|
const rendererTerminalHeight = nativeRenderer.terminalHeight;
|
|
95
96
|
const bitmap = useMemo(() => {
|
|
96
|
-
if (
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
pixelHeight: Math.max(1, Math.round(height * cellHeightPx * scale)),
|
|
108
|
-
};
|
|
97
|
+
if (values.length < 2 || !shouldRenderNativeBitmap(nativeRenderer, nativeCharts === true)) return null;
|
|
98
|
+
const bitmapSize = resolveNativeBitmapSize({
|
|
99
|
+
width,
|
|
100
|
+
height,
|
|
101
|
+
resolution: rendererResolution,
|
|
102
|
+
terminalWidth: rendererTerminalWidth,
|
|
103
|
+
terminalHeight: rendererTerminalHeight,
|
|
104
|
+
cellWidthPx,
|
|
105
|
+
cellHeightPx,
|
|
106
|
+
pixelRatio,
|
|
107
|
+
});
|
|
109
108
|
return renderSparklineBitmap(values, bitmapSize.pixelWidth, bitmapSize.pixelHeight, color, { area, compact: height <= 1 });
|
|
110
109
|
}, [
|
|
111
110
|
area,
|
|
@@ -114,7 +113,9 @@ function TerminalPriceSparkline({
|
|
|
114
113
|
color,
|
|
115
114
|
height,
|
|
116
115
|
nativeCharts,
|
|
116
|
+
nativeRenderer,
|
|
117
117
|
pixelRatio,
|
|
118
|
+
rendererCapabilities,
|
|
118
119
|
rendererResolution,
|
|
119
120
|
rendererTerminalHeight,
|
|
120
121
|
rendererTerminalWidth,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import { Box, ChartSurface, Span, Text, TextAttributes, useNativeRenderer, useUiCapabilities } from "../../ui";
|
|
3
|
-
import {
|
|
3
|
+
import type { NativeChartBitmap } from "../chart/native/chart-rasterizer";
|
|
4
|
+
import { resolveNativeBitmapSize, shouldRenderNativeBitmap } from "../chart/native/bitmap-support";
|
|
4
5
|
import { drawCircle, drawLine, parseHex } from "../chart/native/raster/primitives";
|
|
5
6
|
import { colors } from "../../theme/colors";
|
|
6
7
|
import {
|
|
@@ -203,29 +204,29 @@ export function TerminalSpeedometerGauge({
|
|
|
203
204
|
const labelRow = useMemo(() => renderLabelRow(gaugeWidth, min, max, segments), [gaugeWidth, max, min, segments]);
|
|
204
205
|
const tickRow = useMemo(() => renderTickRow(gaugeWidth, min, max), [gaugeWidth, max, min]);
|
|
205
206
|
const arcRows = useMemo(() => renderArcRows(value, min, max, gaugeWidth, segments), [gaugeWidth, max, min, segments, value]);
|
|
207
|
+
const rendererCapabilities = nativeRenderer.capabilities;
|
|
206
208
|
const rendererResolution = nativeRenderer.resolution;
|
|
207
209
|
const rendererTerminalWidth = nativeRenderer.terminalWidth;
|
|
208
210
|
const rendererTerminalHeight = nativeRenderer.terminalHeight;
|
|
209
211
|
const bitmap = useMemo<NativeChartBitmap | null>(() => {
|
|
210
|
-
if (!nativeCharts) return null;
|
|
211
|
-
const bitmapSize =
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
const pixelHeight = bitmapSize?.pixelHeight ?? Math.max(1, Math.round(arcRows.length * cellHeightPx * scale));
|
|
212
|
+
if (!shouldRenderNativeBitmap(nativeRenderer, nativeCharts === true)) return null;
|
|
213
|
+
const bitmapSize = resolveNativeBitmapSize({
|
|
214
|
+
width: gaugeWidth,
|
|
215
|
+
height: arcRows.length,
|
|
216
|
+
resolution: rendererResolution,
|
|
217
|
+
terminalWidth: rendererTerminalWidth,
|
|
218
|
+
terminalHeight: rendererTerminalHeight,
|
|
219
|
+
cellWidthPx,
|
|
220
|
+
cellHeightPx,
|
|
221
|
+
pixelRatio,
|
|
222
|
+
});
|
|
222
223
|
return renderGaugeBitmap(
|
|
223
224
|
value,
|
|
224
225
|
min,
|
|
225
226
|
max,
|
|
226
227
|
segments,
|
|
227
|
-
pixelWidth,
|
|
228
|
-
pixelHeight,
|
|
228
|
+
bitmapSize.pixelWidth,
|
|
229
|
+
bitmapSize.pixelHeight,
|
|
229
230
|
);
|
|
230
231
|
}, [
|
|
231
232
|
arcRows.length,
|
|
@@ -235,7 +236,9 @@ export function TerminalSpeedometerGauge({
|
|
|
235
236
|
max,
|
|
236
237
|
min,
|
|
237
238
|
nativeCharts,
|
|
239
|
+
nativeRenderer,
|
|
238
240
|
pixelRatio,
|
|
241
|
+
rendererCapabilities,
|
|
239
242
|
rendererResolution,
|
|
240
243
|
rendererTerminalHeight,
|
|
241
244
|
rendererTerminalWidth,
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
useCallback,
|
|
3
3
|
useEffect,
|
|
4
4
|
useRef,
|
|
5
|
-
useState,
|
|
6
5
|
type ReactNode,
|
|
7
6
|
type RefObject,
|
|
8
7
|
} from "react";
|
|
@@ -114,23 +113,16 @@ export function useTableViewState({
|
|
|
114
113
|
headerScrollRef,
|
|
115
114
|
scrollRef,
|
|
116
115
|
syncHeaderScroll,
|
|
117
|
-
hoveredIdx,
|
|
118
|
-
setHoveredIdx,
|
|
119
116
|
}: {
|
|
120
117
|
headerScrollRef?: RefObject<ScrollBoxRenderable | null>;
|
|
121
118
|
scrollRef?: RefObject<ScrollBoxRenderable | null>;
|
|
122
119
|
syncHeaderScroll?: () => void;
|
|
123
|
-
hoveredIdx?: number | null;
|
|
124
|
-
setHoveredIdx?: (index: number | null) => void;
|
|
125
120
|
}) {
|
|
126
121
|
const internalHeaderScrollRef = useRef<ScrollBoxRenderable>(null);
|
|
127
122
|
const internalScrollRef = useRef<ScrollBoxRenderable>(null);
|
|
128
|
-
const [internalHoveredIdx, setInternalHoveredIdx] = useState<number | null>(null);
|
|
129
123
|
|
|
130
124
|
const effectiveHeaderScrollRef = headerScrollRef ?? internalHeaderScrollRef;
|
|
131
125
|
const effectiveScrollRef = scrollRef ?? internalScrollRef;
|
|
132
|
-
const effectiveHoveredIdx = hoveredIdx !== undefined ? hoveredIdx : internalHoveredIdx;
|
|
133
|
-
const effectiveSetHoveredIdx = setHoveredIdx ?? setInternalHoveredIdx;
|
|
134
126
|
|
|
135
127
|
const defaultSyncHeaderScroll = useCallback(() => {
|
|
136
128
|
const body = effectiveScrollRef.current;
|
|
@@ -144,8 +136,6 @@ export function useTableViewState({
|
|
|
144
136
|
return {
|
|
145
137
|
effectiveHeaderScrollRef,
|
|
146
138
|
effectiveScrollRef,
|
|
147
|
-
effectiveHoveredIdx,
|
|
148
|
-
effectiveSetHoveredIdx,
|
|
149
139
|
effectiveSyncHeaderScroll: syncHeaderScroll ?? defaultSyncHeaderScroll,
|
|
150
140
|
};
|
|
151
141
|
}
|
|
@@ -56,8 +56,6 @@ export interface TickerListTableViewProps {
|
|
|
56
56
|
scrollRef?: RefObject<ScrollBoxRenderable | null>;
|
|
57
57
|
syncHeaderScroll?: () => void;
|
|
58
58
|
onBodyScrollActivity?: () => void;
|
|
59
|
-
hoveredIdx?: number | null;
|
|
60
|
-
setHoveredIdx?: (index: number | null) => void;
|
|
61
59
|
keyboardNavigation?: boolean;
|
|
62
60
|
onRootKeyDown?: (event: DataTableKeyEvent) => boolean | void;
|
|
63
61
|
onVisibleRangeChange?: (range: TickerListVisibleRange) => void;
|
|
@@ -119,8 +117,6 @@ export function TickerListTableView({
|
|
|
119
117
|
scrollRef,
|
|
120
118
|
syncHeaderScroll,
|
|
121
119
|
onBodyScrollActivity,
|
|
122
|
-
hoveredIdx,
|
|
123
|
-
setHoveredIdx,
|
|
124
120
|
keyboardNavigation = true,
|
|
125
121
|
onRootKeyDown,
|
|
126
122
|
onVisibleRangeChange,
|
|
@@ -187,7 +183,7 @@ export function TickerListTableView({
|
|
|
187
183
|
ticker: TickerRecord,
|
|
188
184
|
column: ColumnConfig,
|
|
189
185
|
_index: number,
|
|
190
|
-
rowState: { selected: boolean
|
|
186
|
+
rowState: { selected: boolean },
|
|
191
187
|
) => {
|
|
192
188
|
const financials = financialsMap.get(ticker.metadata.ticker);
|
|
193
189
|
if (column.id === PRICE_SPARKLINE_COLUMN_ID) {
|
|
@@ -279,8 +275,6 @@ export function TickerListTableView({
|
|
|
279
275
|
scrollRef={effectiveScrollRef}
|
|
280
276
|
syncHeaderScroll={syncHeaderScroll}
|
|
281
277
|
onBodyScrollActivity={handleBodyScrollActivity}
|
|
282
|
-
hoveredIdx={hoveredIdx}
|
|
283
|
-
setHoveredIdx={setHoveredIdx}
|
|
284
278
|
keyboardNavigation={keyboardNavigation}
|
|
285
279
|
onRootKeyDown={onRootKeyDown}
|
|
286
280
|
resetScrollKey={resetScrollKey}
|
|
@@ -32,8 +32,6 @@ const manyTickers: TickerRecord[] = Array.from({ length: 1000 }, (_, index) => (
|
|
|
32
32
|
},
|
|
33
33
|
}));
|
|
34
34
|
|
|
35
|
-
function noop(_index: number | null): void {}
|
|
36
|
-
|
|
37
35
|
function resolveCell(_column: ColumnConfig, ticker: TickerRecord, _financials: TickerFinancials | undefined): TickerTableCell {
|
|
38
36
|
resolveCellCallCount += 1;
|
|
39
37
|
return { text: ticker.metadata.ticker };
|
|
@@ -69,8 +67,6 @@ function LargeTickerListTableHarness() {
|
|
|
69
67
|
columns={columns}
|
|
70
68
|
tickers={manyTickers}
|
|
71
69
|
cursorSymbol={cursorSymbol}
|
|
72
|
-
hoveredIdx={null}
|
|
73
|
-
setHoveredIdx={noop}
|
|
74
70
|
setCursorSymbol={setCursorSymbol}
|
|
75
71
|
resolveCell={resolveCell}
|
|
76
72
|
financialsMap={financialsMap}
|
|
@@ -40,8 +40,6 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
40
40
|
scrollRef,
|
|
41
41
|
syncHeaderScroll,
|
|
42
42
|
onBodyScrollActivity,
|
|
43
|
-
hoveredIdx,
|
|
44
|
-
setHoveredIdx,
|
|
45
43
|
headerScrollId,
|
|
46
44
|
bodyScrollId,
|
|
47
45
|
getItemKey,
|
|
@@ -369,8 +367,7 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
369
367
|
}
|
|
370
368
|
|
|
371
369
|
const selected = isSelected(item, index);
|
|
372
|
-
const
|
|
373
|
-
const rowState = { selected, hovered };
|
|
370
|
+
const rowState = { selected };
|
|
374
371
|
const rowBackgroundColor = getRowBackgroundColor?.(
|
|
375
372
|
item,
|
|
376
373
|
index,
|
|
@@ -378,9 +375,8 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
378
375
|
);
|
|
379
376
|
const rowBg = selected
|
|
380
377
|
? colors.selected
|
|
381
|
-
:
|
|
382
|
-
|
|
383
|
-
: rowBackgroundColor ?? colors.bg;
|
|
378
|
+
: rowBackgroundColor ?? colors.bg;
|
|
379
|
+
const rowHoverBg = selected ? undefined : hoverBg();
|
|
384
380
|
|
|
385
381
|
return (
|
|
386
382
|
<Box
|
|
@@ -390,10 +386,8 @@ export function OpenTuiDataTable<T, C extends DataTableColumn = DataTableColumn>
|
|
|
390
386
|
{...tableContentWidthProps(contentWidth)}
|
|
391
387
|
paddingX={horizontalPadding}
|
|
392
388
|
backgroundColor={rowBg}
|
|
389
|
+
hoverBackgroundColor={rowHoverBg}
|
|
393
390
|
data-gloom-context-menu-surface={rowContextMenuSurface ? "true" : undefined}
|
|
394
|
-
onMouseMove={() => {
|
|
395
|
-
if (hoveredIdx !== index) setHoveredIdx(index);
|
|
396
|
-
}}
|
|
397
391
|
onMouseDown={(event: any) => {
|
|
398
392
|
focusPane();
|
|
399
393
|
onTableMouseDown?.(event);
|
|
@@ -29,6 +29,10 @@ export interface DataTableSectionHeader {
|
|
|
29
29
|
|
|
30
30
|
export type DataTableScrollAlign = "nearest" | "center";
|
|
31
31
|
|
|
32
|
+
export interface DataTableRowState {
|
|
33
|
+
selected: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
32
36
|
export interface DataTableProps<
|
|
33
37
|
T,
|
|
34
38
|
C extends DataTableColumn = DataTableColumn,
|
|
@@ -42,8 +46,6 @@ export interface DataTableProps<
|
|
|
42
46
|
scrollRef: RefObject<ScrollBoxRenderable | null>;
|
|
43
47
|
syncHeaderScroll: () => void;
|
|
44
48
|
onBodyScrollActivity: () => void;
|
|
45
|
-
hoveredIdx: number | null;
|
|
46
|
-
setHoveredIdx: (index: number | null) => void;
|
|
47
49
|
headerScrollId?: string;
|
|
48
50
|
bodyScrollId?: string;
|
|
49
51
|
getItemKey: (item: T, index: number) => string;
|
|
@@ -58,7 +60,7 @@ export interface DataTableProps<
|
|
|
58
60
|
item: T,
|
|
59
61
|
column: C,
|
|
60
62
|
index: number,
|
|
61
|
-
rowState:
|
|
63
|
+
rowState: DataTableRowState,
|
|
62
64
|
) => DataTableCell;
|
|
63
65
|
renderSectionHeader?: (
|
|
64
66
|
item: T,
|
|
@@ -67,7 +69,7 @@ export interface DataTableProps<
|
|
|
67
69
|
getRowBackgroundColor?: (
|
|
68
70
|
item: T,
|
|
69
71
|
index: number,
|
|
70
|
-
rowState:
|
|
72
|
+
rowState: DataTableRowState,
|
|
71
73
|
) => string | undefined;
|
|
72
74
|
emptyContent?: ReactNode;
|
|
73
75
|
bodyAfter?: ReactNode;
|
|
@@ -166,7 +166,7 @@ export function ListView({
|
|
|
166
166
|
key={item.id}
|
|
167
167
|
height={1}
|
|
168
168
|
backgroundColor={rowBg}
|
|
169
|
-
|
|
169
|
+
onMouseOver={() => {
|
|
170
170
|
if (!disabled) {
|
|
171
171
|
setHoveredIndex((current) => (current === index ? current : index));
|
|
172
172
|
if (selectOnHover) onSelect?.(index);
|
|
@@ -287,7 +287,6 @@ function OpenTuiTabs({
|
|
|
287
287
|
flexDirection="row"
|
|
288
288
|
backgroundColor={active && variant === "pill" ? palette.activeBg : hovered ? palette.hoverBg : undefined}
|
|
289
289
|
onMouseOver={startHover}
|
|
290
|
-
onMouseMove={startHover}
|
|
291
290
|
onMouseOut={endHover}
|
|
292
291
|
onMouseDown={selectTab}
|
|
293
292
|
onDoubleClick={tab.disabled || !tab.onDoubleClick ? undefined : () => tab.onDoubleClick?.(tab.value)}
|
|
@@ -319,7 +318,7 @@ function OpenTuiTabs({
|
|
|
319
318
|
width={addWidth}
|
|
320
319
|
height={1}
|
|
321
320
|
backgroundColor={hoveredValue === "__add__" ? palette.hoverBg : undefined}
|
|
322
|
-
|
|
321
|
+
onMouseOver={() => setHoveredValue((current) => (current === "__add__" ? current : "__add__"))}
|
|
323
322
|
onMouseOut={() => setHoveredValue((current) => (current === "__add__" ? null : current))}
|
|
324
323
|
onMouseDown={(event: TabPointerEvent) => {
|
|
325
324
|
event.preventDefault();
|
|
@@ -51,7 +51,6 @@ function DataTableActivationHarness() {
|
|
|
51
51
|
const headerScrollRef = useRef<ScrollBoxRenderable>(null);
|
|
52
52
|
const scrollRef = useRef<ScrollBoxRenderable>(null);
|
|
53
53
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
54
|
-
const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);
|
|
55
54
|
|
|
56
55
|
return (
|
|
57
56
|
<DataTable
|
|
@@ -64,8 +63,6 @@ function DataTableActivationHarness() {
|
|
|
64
63
|
scrollRef={scrollRef}
|
|
65
64
|
syncHeaderScroll={() => {}}
|
|
66
65
|
onBodyScrollActivity={() => {}}
|
|
67
|
-
hoveredIdx={hoveredIdx}
|
|
68
|
-
setHoveredIdx={setHoveredIdx}
|
|
69
66
|
getItemKey={(row) => row.id}
|
|
70
67
|
isSelected={(row) => selectedId === row.id}
|
|
71
68
|
onSelect={(row) => {
|
|
@@ -89,7 +86,6 @@ function DataTableSectionHarness() {
|
|
|
89
86
|
const headerScrollRef = useRef<ScrollBoxRenderable>(null);
|
|
90
87
|
const scrollRef = useRef<ScrollBoxRenderable>(null);
|
|
91
88
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
92
|
-
const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);
|
|
93
89
|
const rows: SectionTableRow[] = [
|
|
94
90
|
{ kind: "header", id: "macro", label: "Macro Releases" },
|
|
95
91
|
{ kind: "row", id: "cpi", name: "CPI" },
|
|
@@ -106,8 +102,6 @@ function DataTableSectionHarness() {
|
|
|
106
102
|
scrollRef={scrollRef}
|
|
107
103
|
syncHeaderScroll={() => {}}
|
|
108
104
|
onBodyScrollActivity={() => {}}
|
|
109
|
-
hoveredIdx={hoveredIdx}
|
|
110
|
-
setHoveredIdx={setHoveredIdx}
|
|
111
105
|
getItemKey={(row) => row.id}
|
|
112
106
|
isSelected={(row) => row.kind === "row" && row.id === selectedId}
|
|
113
107
|
onSelect={(row) => {
|
|
@@ -211,7 +205,6 @@ function DataTableColumnGapHarness() {
|
|
|
211
205
|
function DataTableVirtualizationHarness() {
|
|
212
206
|
const headerScrollRef = useRef<ScrollBoxRenderable>(null);
|
|
213
207
|
const scrollRef = useRef<ScrollBoxRenderable>(null);
|
|
214
|
-
const [hoveredIdx, setHoveredIdx] = useState<number | null>(null);
|
|
215
208
|
const rows = Array.from({ length: 100 }, (_, index) => ({
|
|
216
209
|
id: `row-${index}`,
|
|
217
210
|
name: `Row ${index}`,
|
|
@@ -237,8 +230,6 @@ function DataTableVirtualizationHarness() {
|
|
|
237
230
|
scrollRef={scrollRef}
|
|
238
231
|
syncHeaderScroll={() => {}}
|
|
239
232
|
onBodyScrollActivity={() => {}}
|
|
240
|
-
hoveredIdx={hoveredIdx}
|
|
241
|
-
setHoveredIdx={setHoveredIdx}
|
|
242
233
|
getItemKey={(row) => row.id}
|
|
243
234
|
isSelected={() => false}
|
|
244
235
|
onSelect={() => {}}
|