@teaui/core 1.1.4
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/Buffer.d.ts +21 -0
- package/.dist/Buffer.js +140 -0
- package/.dist/Buffer.js.map +1 -0
- package/.dist/Color.d.ts +7 -0
- package/.dist/Color.js +39 -0
- package/.dist/Color.js.map +1 -0
- package/.dist/Container.d.ts +21 -0
- package/.dist/Container.js +138 -0
- package/.dist/Container.js.map +1 -0
- package/.dist/Screen.d.ts +54 -0
- package/.dist/Screen.js +278 -0
- package/.dist/Screen.js.map +1 -0
- package/.dist/Style.d.ts +46 -0
- package/.dist/Style.js +433 -0
- package/.dist/Style.js.map +1 -0
- package/.dist/System.d.ts +13 -0
- package/.dist/System.js +26 -0
- package/.dist/System.js.map +1 -0
- package/.dist/Theme.d.ts +56 -0
- package/.dist/Theme.js +157 -0
- package/.dist/Theme.js.map +1 -0
- package/.dist/UI.d.ts +2 -0
- package/.dist/UI.js +28 -0
- package/.dist/UI.js.map +1 -0
- package/.dist/View.d.ts +99 -0
- package/.dist/View.js +374 -0
- package/.dist/View.js.map +1 -0
- package/.dist/Viewport.d.ts +89 -0
- package/.dist/Viewport.js +295 -0
- package/.dist/Viewport.js.map +1 -0
- package/.dist/ansi.d.ts +31 -0
- package/.dist/ansi.js +139 -0
- package/.dist/ansi.js.map +1 -0
- package/.dist/components/Accordion.d.ts +47 -0
- package/.dist/components/Accordion.js +294 -0
- package/.dist/components/Accordion.js.map +1 -0
- package/.dist/components/Box.d.ts +67 -0
- package/.dist/components/Box.js +211 -0
- package/.dist/components/Box.js.map +1 -0
- package/.dist/components/Button.d.ts +28 -0
- package/.dist/components/Button.js +118 -0
- package/.dist/components/Button.js.map +1 -0
- package/.dist/components/Checkbox.d.ts +31 -0
- package/.dist/components/Checkbox.js +106 -0
- package/.dist/components/Checkbox.js.map +1 -0
- package/.dist/components/Collapsible.d.ts +32 -0
- package/.dist/components/Collapsible.js +109 -0
- package/.dist/components/Collapsible.js.map +1 -0
- package/.dist/components/CollapsibleText.d.ts +21 -0
- package/.dist/components/CollapsibleText.js +113 -0
- package/.dist/components/CollapsibleText.js.map +1 -0
- package/.dist/components/Digits.d.ts +20 -0
- package/.dist/components/Digits.js +843 -0
- package/.dist/components/Digits.js.map +1 -0
- package/.dist/components/Drawer.d.ts +44 -0
- package/.dist/components/Drawer.js +473 -0
- package/.dist/components/Drawer.js.map +1 -0
- package/.dist/components/Dropdown.d.ts +61 -0
- package/.dist/components/Dropdown.js +367 -0
- package/.dist/components/Dropdown.js.map +1 -0
- package/.dist/components/Header.d.ts +25 -0
- package/.dist/components/Header.js +106 -0
- package/.dist/components/Header.js.map +1 -0
- package/.dist/components/HotKey.d.ts +14 -0
- package/.dist/components/HotKey.js +31 -0
- package/.dist/components/HotKey.js.map +1 -0
- package/.dist/components/Input.d.ts +45 -0
- package/.dist/components/Input.js +1109 -0
- package/.dist/components/Input.js.map +1 -0
- package/.dist/components/Log.d.ts +16 -0
- package/.dist/components/Log.js +122 -0
- package/.dist/components/Log.js.map +1 -0
- package/.dist/components/Progress.d.ts +21 -0
- package/.dist/components/Progress.js +200 -0
- package/.dist/components/Progress.js.map +1 -0
- package/.dist/components/Scrollable.d.ts +50 -0
- package/.dist/components/Scrollable.js +226 -0
- package/.dist/components/Scrollable.js.map +1 -0
- package/.dist/components/ScrollableList.d.ts +70 -0
- package/.dist/components/ScrollableList.js +354 -0
- package/.dist/components/ScrollableList.js.map +1 -0
- package/.dist/components/Separator.d.ts +21 -0
- package/.dist/components/Separator.js +67 -0
- package/.dist/components/Separator.js.map +1 -0
- package/.dist/components/Slider.d.ts +60 -0
- package/.dist/components/Slider.js +341 -0
- package/.dist/components/Slider.js.map +1 -0
- package/.dist/components/Space.d.ts +19 -0
- package/.dist/components/Space.js +45 -0
- package/.dist/components/Space.js.map +1 -0
- package/.dist/components/Spinner.d.ts +16 -0
- package/.dist/components/Spinner.js +48 -0
- package/.dist/components/Spinner.js.map +1 -0
- package/.dist/components/Stack.d.ts +33 -0
- package/.dist/components/Stack.js +285 -0
- package/.dist/components/Stack.js.map +1 -0
- package/.dist/components/Tabs.d.ts +52 -0
- package/.dist/components/Tabs.js +312 -0
- package/.dist/components/Tabs.js.map +1 -0
- package/.dist/components/Text.d.ts +35 -0
- package/.dist/components/Text.js +242 -0
- package/.dist/components/Text.js.map +1 -0
- package/.dist/components/ToggleGroup.d.ts +26 -0
- package/.dist/components/ToggleGroup.js +279 -0
- package/.dist/components/ToggleGroup.js.map +1 -0
- package/.dist/components/Tree.d.ts +21 -0
- package/.dist/components/Tree.js +233 -0
- package/.dist/components/Tree.js.map +1 -0
- package/.dist/components/Window.d.ts +6 -0
- package/.dist/components/Window.js +17 -0
- package/.dist/components/Window.js.map +1 -0
- package/.dist/components/fonts.d.ts +2 -0
- package/.dist/components/fonts.js +39 -0
- package/.dist/components/fonts.js.map +1 -0
- package/.dist/components/index.d.ts +27 -0
- package/.dist/components/index.js +48 -0
- package/.dist/components/index.js.map +1 -0
- package/.dist/components/types.d.ts +6 -0
- package/.dist/components/types.js +20 -0
- package/.dist/components/types.js.map +1 -0
- package/.dist/components/utility/TrackMouse.d.ts +16 -0
- package/.dist/components/utility/TrackMouse.js +53 -0
- package/.dist/components/utility/TrackMouse.js.map +1 -0
- package/.dist/components/utility/index.d.ts +1 -0
- package/.dist/components/utility/index.js +6 -0
- package/.dist/components/utility/index.js.map +1 -0
- package/.dist/events/index.d.ts +12 -0
- package/.dist/events/index.js +20 -0
- package/.dist/events/index.js.map +1 -0
- package/.dist/events/key.d.ts +15 -0
- package/.dist/events/key.js +105 -0
- package/.dist/events/key.js.map +1 -0
- package/.dist/events/mouse.d.ts +65 -0
- package/.dist/events/mouse.js +68 -0
- package/.dist/events/mouse.js.map +1 -0
- package/.dist/events/window.d.ts +6 -0
- package/.dist/events/window.js +3 -0
- package/.dist/events/window.js.map +1 -0
- package/.dist/geometry.d.ts +178 -0
- package/.dist/geometry.js +315 -0
- package/.dist/geometry.js.map +1 -0
- package/.dist/iTerm2.d.ts +20 -0
- package/.dist/iTerm2.js +60 -0
- package/.dist/iTerm2.js.map +1 -0
- package/.dist/index.d.ts +18 -0
- package/.dist/index.js +37 -0
- package/.dist/index.js.map +1 -0
- package/.dist/inspect.d.ts +2 -0
- package/.dist/inspect.js +118 -0
- package/.dist/inspect.js.map +1 -0
- package/.dist/log.d.ts +12 -0
- package/.dist/log.js +56 -0
- package/.dist/log.js.map +1 -0
- package/.dist/managers/FocusManager.d.ts +28 -0
- package/.dist/managers/FocusManager.js +143 -0
- package/.dist/managers/FocusManager.js.map +1 -0
- package/.dist/managers/ModalManager.d.ts +10 -0
- package/.dist/managers/ModalManager.js +67 -0
- package/.dist/managers/ModalManager.js.map +1 -0
- package/.dist/managers/MouseManager.d.ts +21 -0
- package/.dist/managers/MouseManager.js +313 -0
- package/.dist/managers/MouseManager.js.map +1 -0
- package/.dist/managers/TickManager.d.ts +11 -0
- package/.dist/managers/TickManager.js +63 -0
- package/.dist/managers/TickManager.js.map +1 -0
- package/.dist/sys/alias.d.ts +470 -0
- package/.dist/sys/alias.js +487 -0
- package/.dist/sys/alias.js.map +1 -0
- package/.dist/sys/colors.d.ts +10 -0
- package/.dist/sys/colors.js +285 -0
- package/.dist/sys/colors.js.map +1 -0
- package/.dist/sys/gpmclient.d.ts +11 -0
- package/.dist/sys/gpmclient.js +193 -0
- package/.dist/sys/gpmclient.js.map +1 -0
- package/.dist/sys/index.d.ts +4 -0
- package/.dist/sys/index.js +41 -0
- package/.dist/sys/index.js.map +1 -0
- package/.dist/sys/keys.d.ts +4 -0
- package/.dist/sys/keys.js +531 -0
- package/.dist/sys/keys.js.map +1 -0
- package/.dist/sys/program.d.ts +356 -0
- package/.dist/sys/program.js +3739 -0
- package/.dist/sys/program.js.map +1 -0
- package/.dist/sys/tput.d.ts +297 -0
- package/.dist/sys/tput.js +2708 -0
- package/.dist/sys/tput.js.map +1 -0
- package/.dist/sys/unicode.d.ts +11 -0
- package/.dist/sys/unicode.js +619 -0
- package/.dist/sys/unicode.js.map +1 -0
- package/.dist/sys/usr/linux +0 -0
- package/.dist/sys/usr/windows-ansi +0 -0
- package/.dist/sys/usr/xterm +0 -0
- package/.dist/sys/usr/xterm-256color +0 -0
- package/.dist/sys/usr/xterm.termcap +243 -0
- package/.dist/sys/usr/xterm.terminfo +1977 -0
- package/.dist/terminal.d.ts +7 -0
- package/.dist/terminal.js +3 -0
- package/.dist/terminal.js.map +1 -0
- package/.dist/util.d.ts +22 -0
- package/.dist/util.js +79 -0
- package/.dist/util.js.map +1 -0
- package/LICENSE +24 -0
- package/package.json +49 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Scrollable = void 0;
|
|
4
|
+
const Container_1 = require("../Container");
|
|
5
|
+
const geometry_1 = require("../geometry");
|
|
6
|
+
const events_1 = require("../events");
|
|
7
|
+
const Style_1 = require("../Style");
|
|
8
|
+
/**
|
|
9
|
+
* Scrollable is meant to scroll _a single view_, ie a Stack view. But all the
|
|
10
|
+
* container views are optimized to check their _visibleRect_, and won't render
|
|
11
|
+
* children that are not in view, saving some CPU cycles.
|
|
12
|
+
*/
|
|
13
|
+
class Scrollable extends Container_1.Container {
|
|
14
|
+
#showScrollbars = true;
|
|
15
|
+
#scrollHeight = 1;
|
|
16
|
+
#scrollWidth = 2;
|
|
17
|
+
#contentOffset;
|
|
18
|
+
#contentSize = geometry_1.Size.zero;
|
|
19
|
+
#visibleSize = geometry_1.Size.zero;
|
|
20
|
+
#prevMouseDown = undefined;
|
|
21
|
+
constructor(props) {
|
|
22
|
+
super(props);
|
|
23
|
+
this.#contentOffset = { x: 0, y: 0 };
|
|
24
|
+
this.#update(props);
|
|
25
|
+
}
|
|
26
|
+
update(props) {
|
|
27
|
+
this.#update(props);
|
|
28
|
+
super.update(props);
|
|
29
|
+
}
|
|
30
|
+
#update({ scrollHeight, scrollWidth, showScrollbars }) {
|
|
31
|
+
this.#showScrollbars = showScrollbars ?? true;
|
|
32
|
+
this.#scrollHeight = scrollHeight ?? 1;
|
|
33
|
+
this.#scrollWidth = scrollWidth ?? 2;
|
|
34
|
+
}
|
|
35
|
+
naturalSize(available) {
|
|
36
|
+
const size = super.naturalSize(available).mutableCopy();
|
|
37
|
+
size.width = Math.min(size.width, available.width);
|
|
38
|
+
size.height = Math.min(size.height, available.height);
|
|
39
|
+
return size;
|
|
40
|
+
}
|
|
41
|
+
#maxOffsetX() {
|
|
42
|
+
const tooTall = this.#contentSize.height > this.contentSize.height;
|
|
43
|
+
return this.#visibleSize.width - this.#contentSize.width + (tooTall ? 0 : 1);
|
|
44
|
+
}
|
|
45
|
+
#maxOffsetY() {
|
|
46
|
+
const tooWide = this.#contentSize.width > this.contentSize.width;
|
|
47
|
+
return (this.#visibleSize.height - this.#contentSize.height + (tooWide ? 0 : 1));
|
|
48
|
+
}
|
|
49
|
+
receiveMouse(event) {
|
|
50
|
+
if ((0, events_1.isMouseWheel)(event)) {
|
|
51
|
+
this.receiveWheel(event);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (event.name === 'mouse.button.up') {
|
|
55
|
+
this.#prevMouseDown = undefined;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const tooWide = this.#contentSize.width > this.contentSize.width;
|
|
59
|
+
const tooTall = this.#contentSize.height > this.contentSize.height;
|
|
60
|
+
if (tooWide &&
|
|
61
|
+
tooTall &&
|
|
62
|
+
event.position.y === this.contentSize.height - 1 &&
|
|
63
|
+
event.position.x === this.contentSize.width - 1) {
|
|
64
|
+
// bottom-right corner click
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (this.#prevMouseDown === undefined) {
|
|
68
|
+
if (tooWide && event.position.y === this.contentSize.height) {
|
|
69
|
+
this.#prevMouseDown = 'horizontal';
|
|
70
|
+
}
|
|
71
|
+
else if (tooTall && event.position.x === this.contentSize.width) {
|
|
72
|
+
this.#prevMouseDown = 'vertical';
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.receiveMouseDown(event);
|
|
79
|
+
}
|
|
80
|
+
receiveMouseDown(event) {
|
|
81
|
+
const tooWide = this.#contentSize.width > this.contentSize.width;
|
|
82
|
+
const tooTall = this.#contentSize.height > this.contentSize.height;
|
|
83
|
+
if (tooWide && this.#prevMouseDown === 'horizontal') {
|
|
84
|
+
const maxX = this.#maxOffsetX();
|
|
85
|
+
const offsetX = Math.round((0, geometry_1.interpolate)(event.position.x, [0, this.contentSize.width - (tooTall ? 1 : 0)], [0, maxX]));
|
|
86
|
+
this.#contentOffset = {
|
|
87
|
+
x: Math.max(maxX, Math.min(0, offsetX)),
|
|
88
|
+
y: this.#contentOffset.y,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else if (tooTall && this.#prevMouseDown === 'vertical') {
|
|
92
|
+
const maxY = this.#maxOffsetY();
|
|
93
|
+
const offsetY = Math.round((0, geometry_1.interpolate)(event.position.y, [0, this.contentSize.height - (tooWide ? 1 : 0)], [0, maxY]));
|
|
94
|
+
this.#contentOffset = {
|
|
95
|
+
x: this.#contentOffset.x,
|
|
96
|
+
y: Math.max(maxY, Math.min(0, offsetY)),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
receiveWheel(event) {
|
|
101
|
+
let deltaY = 0, deltaX = 0;
|
|
102
|
+
if (event.name === 'mouse.wheel.up') {
|
|
103
|
+
deltaY = this.#scrollHeight * -1;
|
|
104
|
+
}
|
|
105
|
+
else if (event.name === 'mouse.wheel.down') {
|
|
106
|
+
deltaY = this.#scrollHeight;
|
|
107
|
+
}
|
|
108
|
+
else if (event.name === 'mouse.wheel.left') {
|
|
109
|
+
deltaX = this.#scrollWidth;
|
|
110
|
+
}
|
|
111
|
+
else if (event.name === 'mouse.wheel.right') {
|
|
112
|
+
deltaX = this.#scrollWidth * -1;
|
|
113
|
+
}
|
|
114
|
+
if (event.ctrl) {
|
|
115
|
+
deltaY *= 5;
|
|
116
|
+
deltaX *= 5;
|
|
117
|
+
}
|
|
118
|
+
const tooTall = (this.#contentSize?.height ?? 0) > this.contentSize.height;
|
|
119
|
+
if (!tooTall && deltaX === 0) {
|
|
120
|
+
deltaX = deltaY;
|
|
121
|
+
}
|
|
122
|
+
this.scrollBy(deltaX, deltaY);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Moves the visible region. The visible region is stored as a pointer to the
|
|
126
|
+
* top-most row and an offset from the top of that row (see `interface ContentOffset`)
|
|
127
|
+
*
|
|
128
|
+
* Positive offset scrolls *down* (currentOffset goes more negative)
|
|
129
|
+
*
|
|
130
|
+
* When current cell is entirely above the top, we set the `contentOffset` to the
|
|
131
|
+
* row that is at the top of the screen and still visible, similarly if the current
|
|
132
|
+
* cell is below the top, we fetch enough rows about and update the `contentOffset`
|
|
133
|
+
* to point to the top-most row.
|
|
134
|
+
*/
|
|
135
|
+
scrollBy(offsetX, offsetY) {
|
|
136
|
+
if (offsetX === 0 && offsetY === 0) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const tooWide = this.#contentSize.width > this.contentSize.width;
|
|
140
|
+
const tooTall = this.#contentSize.height > this.contentSize.height;
|
|
141
|
+
let { x, y } = this.#contentOffset;
|
|
142
|
+
const maxX = this.#maxOffsetX();
|
|
143
|
+
const maxY = this.#maxOffsetY();
|
|
144
|
+
x = Math.min(0, Math.max(maxX, x - offsetX));
|
|
145
|
+
y = Math.min(0, Math.max(maxY, y - offsetY));
|
|
146
|
+
this.#contentOffset = { x, y };
|
|
147
|
+
}
|
|
148
|
+
get contentSize() {
|
|
149
|
+
const delta = this.#showScrollbars ? 1 : 0;
|
|
150
|
+
return super.contentSize.shrink(delta, delta);
|
|
151
|
+
}
|
|
152
|
+
render(viewport) {
|
|
153
|
+
if (viewport.isEmpty) {
|
|
154
|
+
return super.render(viewport);
|
|
155
|
+
}
|
|
156
|
+
viewport.registerMouse('mouse.wheel');
|
|
157
|
+
let contentSize = geometry_1.Size.zero.mutableCopy();
|
|
158
|
+
for (const child of this.children) {
|
|
159
|
+
const childSize = child.naturalSize(viewport.contentSize);
|
|
160
|
+
contentSize.width = Math.max(contentSize.width, childSize.width);
|
|
161
|
+
contentSize.height = Math.max(contentSize.height, childSize.height);
|
|
162
|
+
}
|
|
163
|
+
this.#contentSize = contentSize;
|
|
164
|
+
const tooWide = contentSize.width > viewport.contentSize.width;
|
|
165
|
+
const tooTall = contentSize.height > viewport.contentSize.height;
|
|
166
|
+
// #contentOffset is _negative_ (indicates the amount to move the view away
|
|
167
|
+
// from the origin, which will always be up/left of 0,0)
|
|
168
|
+
const outside = new geometry_1.Rect([this.#contentOffset.x, this.#contentOffset.y], viewport.contentSize
|
|
169
|
+
.shrink(this.#contentOffset.x, this.#contentOffset.y)
|
|
170
|
+
.shrink(this.#showScrollbars && tooTall ? 1 : 0, this.#showScrollbars && tooWide ? 1 : 0));
|
|
171
|
+
viewport.clipped(outside, inside => {
|
|
172
|
+
for (const child of this.children) {
|
|
173
|
+
child.render(inside);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
this.#visibleSize = viewport.visibleRect.size.shrink(tooWide ? 1 : 0, tooTall ? 1 : 0);
|
|
177
|
+
if (this.#showScrollbars && (tooWide || tooTall)) {
|
|
178
|
+
const scrollBar = new Style_1.Style({
|
|
179
|
+
foreground: this.theme.darkenColor,
|
|
180
|
+
background: this.theme.darkenColor,
|
|
181
|
+
});
|
|
182
|
+
const scrollControl = new Style_1.Style({
|
|
183
|
+
foreground: this.theme.highlightColor,
|
|
184
|
+
background: this.theme.highlightColor,
|
|
185
|
+
});
|
|
186
|
+
// scrollMaxX: x of the last column of the view
|
|
187
|
+
// scrollMaxY: y of the last row of the view
|
|
188
|
+
// scrollMaxHorizX: horizontal scroll bar is drawn from 0 to scrollMaxHorizX
|
|
189
|
+
// scrollMaxHorizY: vertical scroll bar is drawn from 0 to scrollMaxHorizY
|
|
190
|
+
const scrollMaxX = viewport.contentSize.width - 1, scrollMaxY = viewport.contentSize.height - 1, scrollMaxHorizX = scrollMaxX - (tooTall ? 1 : 0), scrollMaxVertY = scrollMaxY - (tooWide ? 1 : 0);
|
|
191
|
+
if (tooWide && tooTall) {
|
|
192
|
+
viewport.write('█', new geometry_1.Point(scrollMaxX, scrollMaxY), scrollBar);
|
|
193
|
+
}
|
|
194
|
+
if (tooWide) {
|
|
195
|
+
viewport.registerMouse('mouse.button.left', new geometry_1.Rect(new geometry_1.Point(0, scrollMaxY), new geometry_1.Size(scrollMaxHorizX + 1, 1)));
|
|
196
|
+
const contentOffsetX = -this.#contentOffset.x;
|
|
197
|
+
const viewX = Math.round((0, geometry_1.interpolate)(contentOffsetX, [
|
|
198
|
+
0,
|
|
199
|
+
contentSize.width -
|
|
200
|
+
viewport.contentSize.width +
|
|
201
|
+
(tooTall ? 1 : 0),
|
|
202
|
+
], [0, scrollMaxHorizX]));
|
|
203
|
+
for (let x = 0; x <= scrollMaxHorizX; x++) {
|
|
204
|
+
const inRange = x === viewX;
|
|
205
|
+
viewport.write(inRange ? '█' : ' ', new geometry_1.Point(x, scrollMaxY), inRange ? scrollControl : scrollBar);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (tooTall) {
|
|
209
|
+
viewport.registerMouse('mouse.button.left', new geometry_1.Rect(new geometry_1.Point(scrollMaxX, 0), new geometry_1.Size(1, scrollMaxVertY + 1)));
|
|
210
|
+
const contentOffsetY = -this.#contentOffset.y;
|
|
211
|
+
const viewY = Math.round((0, geometry_1.interpolate)(contentOffsetY, [
|
|
212
|
+
0,
|
|
213
|
+
contentSize.height -
|
|
214
|
+
viewport.contentSize.height +
|
|
215
|
+
(tooWide ? 1 : 0),
|
|
216
|
+
], [0, scrollMaxVertY]));
|
|
217
|
+
for (let y = 0; y <= scrollMaxVertY; y++) {
|
|
218
|
+
const inRange = y === viewY;
|
|
219
|
+
viewport.write(inRange ? '█' : ' ', new geometry_1.Point(scrollMaxX, y), inRange ? scrollControl : scrollBar);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.Scrollable = Scrollable;
|
|
226
|
+
//# sourceMappingURL=Scrollable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Scrollable.js","sourceRoot":"","sources":["../../lib/components/Scrollable.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Viewport } from '../Viewport';
|
|
2
|
+
import { type Props as ViewProps, View } from '../View';
|
|
3
|
+
import { Container } from '../Container';
|
|
4
|
+
import { Size } from '../geometry';
|
|
5
|
+
import { type MouseEvent } from '../events';
|
|
6
|
+
interface Props<T> extends ViewProps {
|
|
7
|
+
items: T[];
|
|
8
|
+
cellForItem: (item: T, row: number) => View;
|
|
9
|
+
/**
|
|
10
|
+
* Show/hide the scrollbars
|
|
11
|
+
* @default true
|
|
12
|
+
*/
|
|
13
|
+
showScrollbars?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* How many rows to scroll by when using the mouse wheel.
|
|
16
|
+
* @default 1
|
|
17
|
+
*/
|
|
18
|
+
scrollHeight?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Useful for log views
|
|
21
|
+
*/
|
|
22
|
+
keepAtBottom?: boolean;
|
|
23
|
+
}
|
|
24
|
+
interface ContentOffset {
|
|
25
|
+
row: number;
|
|
26
|
+
offset: number;
|
|
27
|
+
}
|
|
28
|
+
export declare class ScrollableList<T> extends Container {
|
|
29
|
+
#private;
|
|
30
|
+
constructor({ cellForItem, items, keepAtBottom, scrollHeight, showScrollbars, ...viewProps }: Props<T>);
|
|
31
|
+
update(props: Props<T>): void;
|
|
32
|
+
naturalSize(available: Size): Size;
|
|
33
|
+
/**
|
|
34
|
+
* Tells ScrollableList to re-fetch all rows.
|
|
35
|
+
*/
|
|
36
|
+
invalidate(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Tells ScrollableList to re-fetch the visible rows.
|
|
39
|
+
* @param forCache: 'size' | 'view' representing which cache to invalidate
|
|
40
|
+
*/
|
|
41
|
+
invalidateAllRows(forCache: 'size' | 'view'): void;
|
|
42
|
+
/**
|
|
43
|
+
* Tells ScrollableList to refetch a specific row
|
|
44
|
+
* @param row: the row to invalidate
|
|
45
|
+
* @param forCache: 'size' | 'view' representing which cache to invalidate
|
|
46
|
+
*/
|
|
47
|
+
invalidateItem(item: T, forCache: 'size' | 'view'): void;
|
|
48
|
+
invalidateSize(): void;
|
|
49
|
+
receiveMouse(event: MouseEvent): void;
|
|
50
|
+
/**
|
|
51
|
+
* Moves the visible region. The visible region is stored as a pointer to the
|
|
52
|
+
* top-most row and an offset from the top of that row (see `interface ContentOffset`)
|
|
53
|
+
*
|
|
54
|
+
* Positive offset scrolls *down* (currentOffset goes more negative)
|
|
55
|
+
*
|
|
56
|
+
* When current cell is entirely above the top, we set the `contentOffset` to the
|
|
57
|
+
* row that is at the top of the screen and still visible, similarly if the current
|
|
58
|
+
* cell is below the top, we fetch enough rows about and update the `contentOffset`
|
|
59
|
+
* to point to the top-most row.
|
|
60
|
+
*/
|
|
61
|
+
scrollBy(offset: number): void;
|
|
62
|
+
updateItems(items: T[]): void;
|
|
63
|
+
viewForRow(row: number): View | undefined;
|
|
64
|
+
sizeForRow(row: number, contentWidth: number, view: View): Size;
|
|
65
|
+
sizeForRow(row: number, contentWidth: number): Size | undefined;
|
|
66
|
+
get contentSize(): Size;
|
|
67
|
+
lastOffset(): ContentOffset;
|
|
68
|
+
render(viewport: Viewport): void;
|
|
69
|
+
}
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ScrollableList = void 0;
|
|
4
|
+
const Container_1 = require("../Container");
|
|
5
|
+
const Style_1 = require("../Style");
|
|
6
|
+
const geometry_1 = require("../geometry");
|
|
7
|
+
const events_1 = require("../events");
|
|
8
|
+
class ScrollableList extends Container_1.Container {
|
|
9
|
+
/**
|
|
10
|
+
* Your function here need not return "stable" views; the views returned by this
|
|
11
|
+
* function will be cached until you call `scrollableList.invalidateCache()` or
|
|
12
|
+
* `scrollableList.invalidateRow(row)`.
|
|
13
|
+
*/
|
|
14
|
+
#items;
|
|
15
|
+
#cellForItem;
|
|
16
|
+
#keepAtBottom;
|
|
17
|
+
#isAtBottom = true;
|
|
18
|
+
#showScrollbars;
|
|
19
|
+
#scrollHeight;
|
|
20
|
+
#contentOffset;
|
|
21
|
+
#maxWidth = 0;
|
|
22
|
+
#viewCache = new Map();
|
|
23
|
+
#sizeCache = new Map();
|
|
24
|
+
#totalHeight;
|
|
25
|
+
constructor({ cellForItem, items, keepAtBottom, scrollHeight, showScrollbars, ...viewProps }) {
|
|
26
|
+
super(viewProps);
|
|
27
|
+
this.#showScrollbars = showScrollbars ?? true;
|
|
28
|
+
this.#contentOffset = { row: 0, offset: 0 };
|
|
29
|
+
this.#cellForItem = cellForItem;
|
|
30
|
+
this.#scrollHeight = scrollHeight ?? 1;
|
|
31
|
+
this.#items = items;
|
|
32
|
+
this.#keepAtBottom = keepAtBottom ?? false;
|
|
33
|
+
}
|
|
34
|
+
update(props) {
|
|
35
|
+
this.#update(props);
|
|
36
|
+
super.update(props);
|
|
37
|
+
}
|
|
38
|
+
#update({}) { }
|
|
39
|
+
naturalSize(available) {
|
|
40
|
+
let { row, offset: y } = this.#contentOffset;
|
|
41
|
+
const scrollWidth = this.#showScrollbars ? 1 : 0;
|
|
42
|
+
while (y < available.height) {
|
|
43
|
+
const view = this.viewForRow(row);
|
|
44
|
+
if (!view) {
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
const rowSize = this.sizeForRow(row, available.width - scrollWidth, view);
|
|
48
|
+
// persist #maxWidth so that the largest row _remains_ the largest row even
|
|
49
|
+
// after it scrolls out of the visible window
|
|
50
|
+
this.#maxWidth = Math.max(this.#maxWidth, rowSize.width);
|
|
51
|
+
y += rowSize.height;
|
|
52
|
+
row += 1;
|
|
53
|
+
}
|
|
54
|
+
return new geometry_1.Size(this.#maxWidth + scrollWidth, available.height);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Tells ScrollableList to re-fetch all rows.
|
|
58
|
+
*/
|
|
59
|
+
invalidate() {
|
|
60
|
+
this.#maxWidth = 0;
|
|
61
|
+
this.invalidateAllRows('view');
|
|
62
|
+
super.invalidateSize();
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Tells ScrollableList to re-fetch the visible rows.
|
|
66
|
+
* @param forCache: 'size' | 'view' representing which cache to invalidate
|
|
67
|
+
*/
|
|
68
|
+
invalidateAllRows(forCache) {
|
|
69
|
+
if (forCache === 'view') {
|
|
70
|
+
this.#viewCache = new Map();
|
|
71
|
+
}
|
|
72
|
+
this.#sizeCache = new Map();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Tells ScrollableList to refetch a specific row
|
|
76
|
+
* @param row: the row to invalidate
|
|
77
|
+
* @param forCache: 'size' | 'view' representing which cache to invalidate
|
|
78
|
+
*/
|
|
79
|
+
invalidateItem(item, forCache) {
|
|
80
|
+
if (forCache === 'view') {
|
|
81
|
+
this.#viewCache.delete(item);
|
|
82
|
+
}
|
|
83
|
+
this.#sizeCache.delete(item);
|
|
84
|
+
}
|
|
85
|
+
invalidateSize() {
|
|
86
|
+
this.#maxWidth = 0;
|
|
87
|
+
this.invalidateAllRows('size');
|
|
88
|
+
super.invalidateSize();
|
|
89
|
+
}
|
|
90
|
+
receiveMouse(event) {
|
|
91
|
+
if (event.name === 'mouse.wheel.up') {
|
|
92
|
+
this.scrollBy(this.#scrollHeight * -1);
|
|
93
|
+
}
|
|
94
|
+
else if (event.name === 'mouse.wheel.down') {
|
|
95
|
+
this.scrollBy(this.#scrollHeight);
|
|
96
|
+
}
|
|
97
|
+
else if ((0, events_1.isMouseDragging)(event) && this.#totalHeight) {
|
|
98
|
+
if (this.#totalHeight <= this.contentSize.height) {
|
|
99
|
+
this.#contentOffset = { row: 0, offset: 0 };
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const maxY = this.#totalHeight - this.contentSize.height;
|
|
103
|
+
const heightY = Math.round((0, geometry_1.interpolate)(Math.max(0, Math.min(this.contentSize.height - 1, event.position.y)), [0, this.contentSize.height - 1], [0, maxY]));
|
|
104
|
+
this.#isAtBottom = heightY === maxY;
|
|
105
|
+
const cellWidth = this.contentSize.width;
|
|
106
|
+
for (let row = 0, y = 0; row < this.#items.length; row++) {
|
|
107
|
+
const rowHeight = this.sizeForRow(row, cellWidth)?.height;
|
|
108
|
+
if (rowHeight === undefined) {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
if (y + rowHeight >= heightY) {
|
|
112
|
+
this.#contentOffset = { row, offset: y - heightY };
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
y += rowHeight;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Moves the visible region. The visible region is stored as a pointer to the
|
|
121
|
+
* top-most row and an offset from the top of that row (see `interface ContentOffset`)
|
|
122
|
+
*
|
|
123
|
+
* Positive offset scrolls *down* (currentOffset goes more negative)
|
|
124
|
+
*
|
|
125
|
+
* When current cell is entirely above the top, we set the `contentOffset` to the
|
|
126
|
+
* row that is at the top of the screen and still visible, similarly if the current
|
|
127
|
+
* cell is below the top, we fetch enough rows about and update the `contentOffset`
|
|
128
|
+
* to point to the top-most row.
|
|
129
|
+
*/
|
|
130
|
+
scrollBy(offset) {
|
|
131
|
+
if (offset === 0) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
this.invalidateSize();
|
|
135
|
+
const { row, offset: currentOffset } = this.#contentOffset;
|
|
136
|
+
let height = this.sizeForRow(row, this.contentSize.width)?.height;
|
|
137
|
+
if (height === undefined) {
|
|
138
|
+
this.#contentOffset = { row: 0, offset: 0 };
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
// prevent scrolling if there is no more content
|
|
142
|
+
if (offset > 0) {
|
|
143
|
+
const doScroll = this.#checkScrollDown(row, currentOffset, height);
|
|
144
|
+
if (!doScroll) {
|
|
145
|
+
this.#isAtBottom = true;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (row === 0 && currentOffset >= 0) {
|
|
150
|
+
// no helper function necessary here - if offset < 0, do not scroll if we are
|
|
151
|
+
// already at the top
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
this.#isAtBottom = false;
|
|
155
|
+
let nextOffset = currentOffset - offset;
|
|
156
|
+
if (nextOffset <= -height) {
|
|
157
|
+
this.#contentOffset = this.#scrollDownToNextRow(row, nextOffset, height);
|
|
158
|
+
}
|
|
159
|
+
else if (nextOffset > 0) {
|
|
160
|
+
this.#contentOffset = this.#scrollUpToPrevRow(row, nextOffset, height);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
this.#contentOffset = { row: row, offset: nextOffset };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
updateItems(items) {
|
|
167
|
+
this.#items = items;
|
|
168
|
+
this.invalidateAllRows('view');
|
|
169
|
+
this.invalidateSize();
|
|
170
|
+
}
|
|
171
|
+
viewForRow(row) {
|
|
172
|
+
if (row < 0 || row >= this.#items.length) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const item = this.#items[row];
|
|
176
|
+
let view = this.#viewCache.get(item);
|
|
177
|
+
if (!view) {
|
|
178
|
+
view = this.#cellForItem(item, row);
|
|
179
|
+
if (view) {
|
|
180
|
+
this.#viewCache.set(item, view);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return view;
|
|
184
|
+
}
|
|
185
|
+
sizeForRow(row, contentWidth, view) {
|
|
186
|
+
const item = this.#items[row];
|
|
187
|
+
if (contentWidth === this.contentSize.width && item) {
|
|
188
|
+
const size = this.#sizeCache.get(item);
|
|
189
|
+
if (size !== undefined) {
|
|
190
|
+
return size;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
view = view ?? this.viewForRow(row);
|
|
194
|
+
if (view === undefined) {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
const size = view.naturalSize(new geometry_1.Size(contentWidth, 0));
|
|
198
|
+
if (contentWidth === this.contentSize.width && item) {
|
|
199
|
+
this.#sizeCache.set(item, size);
|
|
200
|
+
}
|
|
201
|
+
return size;
|
|
202
|
+
}
|
|
203
|
+
get contentSize() {
|
|
204
|
+
return super.contentSize.shrink(this.#showScrollbars ? 1 : 0, 0);
|
|
205
|
+
}
|
|
206
|
+
lastOffset() {
|
|
207
|
+
const cellCount = this.#items.length;
|
|
208
|
+
const cellWidth = this.contentSize.width;
|
|
209
|
+
let row = cellCount - 1;
|
|
210
|
+
let y = 0;
|
|
211
|
+
while (y < this.contentSize.height) {
|
|
212
|
+
const height = this.sizeForRow(row, cellWidth)?.height;
|
|
213
|
+
if (height === undefined) {
|
|
214
|
+
return { row: 0, offset: 0 };
|
|
215
|
+
}
|
|
216
|
+
y += height;
|
|
217
|
+
if (y >= this.contentSize.height) {
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
row -= 1;
|
|
221
|
+
}
|
|
222
|
+
return { row, offset: this.contentSize.height - y };
|
|
223
|
+
}
|
|
224
|
+
render(viewport) {
|
|
225
|
+
if (viewport.isEmpty) {
|
|
226
|
+
return super.render(viewport);
|
|
227
|
+
}
|
|
228
|
+
viewport.registerMouse('mouse.wheel');
|
|
229
|
+
if (this.#contentOffset.row >= this.#items.length ||
|
|
230
|
+
(this.#keepAtBottom && this.#isAtBottom)) {
|
|
231
|
+
const offset = this.lastOffset();
|
|
232
|
+
this.#contentOffset = offset;
|
|
233
|
+
}
|
|
234
|
+
const cellWidth = this.contentSize.width;
|
|
235
|
+
const prevRows = new Set(this.children);
|
|
236
|
+
const visibleRows = new Set();
|
|
237
|
+
let { row, offset: y } = this.#contentOffset;
|
|
238
|
+
let heights = [0, 0, 0];
|
|
239
|
+
if (this.#showScrollbars) {
|
|
240
|
+
for (let i = 0; i < row; i++) {
|
|
241
|
+
heights[0] += this.sizeForRow(i, cellWidth)?.height ?? 0;
|
|
242
|
+
}
|
|
243
|
+
heights[1] = heights[0];
|
|
244
|
+
}
|
|
245
|
+
while (y < viewport.contentSize.height) {
|
|
246
|
+
const view = this.viewForRow(row);
|
|
247
|
+
if (!view) {
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
const height = this.sizeForRow(row, cellWidth, view)?.height;
|
|
251
|
+
if (y === this.#contentOffset.offset && y + height <= 0) {
|
|
252
|
+
y = this.#contentOffset.offset = 0;
|
|
253
|
+
}
|
|
254
|
+
row += 1;
|
|
255
|
+
heights[1] += height;
|
|
256
|
+
if (view.parent !== this) {
|
|
257
|
+
this.add(view);
|
|
258
|
+
}
|
|
259
|
+
visibleRows.add(view);
|
|
260
|
+
if (y < viewport.visibleRect.maxY() &&
|
|
261
|
+
y + height >= viewport.visibleRect.minY()) {
|
|
262
|
+
const rect = new geometry_1.Rect(new geometry_1.Point(0, y), new geometry_1.Size(cellWidth, height));
|
|
263
|
+
viewport.clipped(rect, inside => {
|
|
264
|
+
view.render(inside);
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
y += height;
|
|
268
|
+
if (y >= viewport.contentSize.height) {
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
for (const prevRow of prevRows) {
|
|
273
|
+
if (!visibleRows.has(prevRow)) {
|
|
274
|
+
this.removeChild(prevRow);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (this.#showScrollbars) {
|
|
278
|
+
viewport.registerMouse('mouse.button.left', new geometry_1.Rect(new geometry_1.Point(cellWidth, 0), new geometry_1.Size(1, viewport.contentSize.height)));
|
|
279
|
+
heights[2] = heights[1];
|
|
280
|
+
for (let i = row; i < this.#items.length; i++) {
|
|
281
|
+
const rowHeight = this.sizeForRow(i, cellWidth)?.height;
|
|
282
|
+
if (rowHeight === undefined) {
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
heights[2] += rowHeight;
|
|
286
|
+
}
|
|
287
|
+
this.#totalHeight = heights[2];
|
|
288
|
+
for (let y = 0; y < viewport.contentSize.height; y++) {
|
|
289
|
+
const h = (0, geometry_1.interpolate)(y, [0, viewport.contentSize.height - 1], [0, heights[2]]);
|
|
290
|
+
const inRange = ~~h >= heights[0] && ~~h <= heights[1] + 1;
|
|
291
|
+
viewport.write(inRange ? '█' : ' ', new geometry_1.Point(cellWidth, y), new Style_1.Style(inRange
|
|
292
|
+
? {
|
|
293
|
+
foreground: this.theme.highlightColor,
|
|
294
|
+
background: this.theme.highlightColor,
|
|
295
|
+
}
|
|
296
|
+
: {
|
|
297
|
+
foreground: this.theme.darkenColor,
|
|
298
|
+
background: this.theme.darkenColor,
|
|
299
|
+
}));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Returns 'true' if the scroll should be allowed, returns 'false' if there
|
|
305
|
+
* is no more content to be shown (do not scroll down)
|
|
306
|
+
*/
|
|
307
|
+
#checkScrollDown(row, currentOffset, height) {
|
|
308
|
+
// add heights of visible cells – if we run out of cells before
|
|
309
|
+
// y > this.contentSize, exit. Otherwise, scroll.
|
|
310
|
+
let y = currentOffset;
|
|
311
|
+
let nextRow = row;
|
|
312
|
+
let nextHeight = height;
|
|
313
|
+
while (nextHeight !== undefined) {
|
|
314
|
+
y += nextHeight;
|
|
315
|
+
if (y > this.contentSize.height) {
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
nextHeight = this.sizeForRow(++nextRow, this.contentSize.width)?.height;
|
|
319
|
+
if (nextHeight === undefined) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
#scrollDownToNextRow(row, nextOffset, height) {
|
|
325
|
+
let nextRow = row;
|
|
326
|
+
while (nextOffset <= -height) {
|
|
327
|
+
const nextHeight = this.sizeForRow(nextRow + 1, this.contentSize.width)?.height;
|
|
328
|
+
if (nextHeight === undefined) {
|
|
329
|
+
nextOffset = -height;
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
nextOffset += height;
|
|
333
|
+
height = nextHeight;
|
|
334
|
+
nextRow += 1;
|
|
335
|
+
}
|
|
336
|
+
return { row: nextRow, offset: nextOffset };
|
|
337
|
+
}
|
|
338
|
+
#scrollUpToPrevRow(row, nextOffset, height) {
|
|
339
|
+
let nextRow = row;
|
|
340
|
+
while (nextOffset > 0) {
|
|
341
|
+
const nextHeight = this.sizeForRow(nextRow - 1, this.contentSize.width)?.height;
|
|
342
|
+
if (nextHeight === undefined) {
|
|
343
|
+
nextOffset = 0;
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
height = nextHeight;
|
|
347
|
+
nextOffset -= height;
|
|
348
|
+
nextRow -= 1;
|
|
349
|
+
}
|
|
350
|
+
return { row: nextRow, offset: nextOffset };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
exports.ScrollableList = ScrollableList;
|
|
354
|
+
//# sourceMappingURL=ScrollableList.js.map
|