@nmakarov/cli-toolkit 0.80.0 → 0.81.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/cli-runner.cjs +59 -26
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +59 -26
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +63 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +59 -26
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +59 -26
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +59 -26
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +59 -26
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +55 -26
- package/dist/screen.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-runner.js
CHANGED
|
@@ -1002,6 +1002,30 @@ var init_ui_elements = __esm({
|
|
|
1002
1002
|
}
|
|
1003
1003
|
});
|
|
1004
1004
|
|
|
1005
|
+
// src/screen/follow-scroll.js
|
|
1006
|
+
function clampScroll(scrollTop, maxScroll) {
|
|
1007
|
+
const max = Math.max(0, Number(maxScroll) || 0);
|
|
1008
|
+
const top = Number(scrollTop) || 0;
|
|
1009
|
+
return Math.min(Math.max(0, top), max);
|
|
1010
|
+
}
|
|
1011
|
+
function isScrolledToBottom(scrollTop, maxScroll) {
|
|
1012
|
+
return clampScroll(scrollTop, maxScroll) >= Math.max(0, Number(maxScroll) || 0);
|
|
1013
|
+
}
|
|
1014
|
+
function nextScrollAfterUserMove(scrollTop, maxScroll, delta) {
|
|
1015
|
+
const next = clampScroll((Number(scrollTop) || 0) + (Number(delta) || 0), maxScroll);
|
|
1016
|
+
return { scrollTop: next, following: isScrolledToBottom(next, maxScroll) };
|
|
1017
|
+
}
|
|
1018
|
+
function nextScrollAfterContentChange({ following, scrollTop, maxScroll }) {
|
|
1019
|
+
const max = Math.max(0, Number(maxScroll) || 0);
|
|
1020
|
+
if (following) return { scrollTop: max, following: true };
|
|
1021
|
+
const next = clampScroll(scrollTop, max);
|
|
1022
|
+
return { scrollTop: next, following: isScrolledToBottom(next, max) };
|
|
1023
|
+
}
|
|
1024
|
+
var init_follow_scroll = __esm({
|
|
1025
|
+
"src/screen/follow-scroll.js"() {
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1005
1029
|
// src/screen/scrollable-text.js
|
|
1006
1030
|
import { useState as useState3, useEffect as useEffect2, useMemo, useRef as useRef2, createElement as createElement2 } from "react";
|
|
1007
1031
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
@@ -1036,9 +1060,11 @@ function ScrollableText({
|
|
|
1036
1060
|
showScrollbar = true,
|
|
1037
1061
|
showStatus = true,
|
|
1038
1062
|
bindKeys = true,
|
|
1039
|
-
header = null
|
|
1063
|
+
header = null,
|
|
1064
|
+
followBottom = false
|
|
1040
1065
|
}) {
|
|
1041
1066
|
const [scrollTop, setScrollTop] = useState3(0);
|
|
1067
|
+
const [following, setFollowing] = useState3(() => !!followBottom);
|
|
1042
1068
|
const [, bump] = useState3(0);
|
|
1043
1069
|
const termRows = process.stdout.rows || 24;
|
|
1044
1070
|
const viewportRows = Math.max(
|
|
@@ -1057,39 +1083,40 @@ function ScrollableText({
|
|
|
1057
1083
|
const clamped = Math.min(Math.max(0, scrollTop), maxScroll);
|
|
1058
1084
|
const visible = allLines.slice(clamped, clamped + viewportRows);
|
|
1059
1085
|
const bar = needsBar ? scrollbarGlyphs(viewportRows, allLines.length, clamped) : null;
|
|
1060
|
-
useEffect2(() => {
|
|
1061
|
-
setScrollTop((s) => Math.min(s, maxScroll));
|
|
1062
|
-
}, [maxScroll]);
|
|
1063
1086
|
const maxScrollRef = useRef2(maxScroll);
|
|
1064
1087
|
const pageSizeRef = useRef2(viewportRows);
|
|
1088
|
+
const scrollTopRef = useRef2(scrollTop);
|
|
1089
|
+
const followingRef = useRef2(following);
|
|
1065
1090
|
maxScrollRef.current = maxScroll;
|
|
1066
1091
|
pageSizeRef.current = viewportRows;
|
|
1092
|
+
scrollTopRef.current = scrollTop;
|
|
1093
|
+
followingRef.current = following;
|
|
1094
|
+
useEffect2(() => {
|
|
1095
|
+
const next = nextScrollAfterContentChange({
|
|
1096
|
+
following: followBottom && followingRef.current,
|
|
1097
|
+
scrollTop: scrollTopRef.current,
|
|
1098
|
+
maxScroll
|
|
1099
|
+
});
|
|
1100
|
+
if (next.scrollTop !== scrollTopRef.current) setScrollTop(next.scrollTop);
|
|
1101
|
+
if (followBottom && next.following !== followingRef.current) setFollowing(next.following);
|
|
1102
|
+
}, [maxScroll, followBottom]);
|
|
1103
|
+
const applyUserScroll = (delta) => {
|
|
1104
|
+
const next = nextScrollAfterUserMove(scrollTopRef.current, maxScrollRef.current, delta);
|
|
1105
|
+
setScrollTop(next.scrollTop);
|
|
1106
|
+
if (followBottom) setFollowing(next.following);
|
|
1107
|
+
bump((n) => n + 1);
|
|
1108
|
+
ctx?.update?.();
|
|
1109
|
+
};
|
|
1067
1110
|
useEffect2(() => {
|
|
1068
1111
|
if (!ctx || !bindKeys) return void 0;
|
|
1069
1112
|
ctx.setKeyBinding(SCROLL_KEYS);
|
|
1070
|
-
ctx.setAction("scrollUp", () =>
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
});
|
|
1075
|
-
ctx.setAction("scrollDown", () => {
|
|
1076
|
-
setScrollTop((s) => Math.min(maxScrollRef.current, s + 1));
|
|
1077
|
-
bump((n) => n + 1);
|
|
1078
|
-
ctx.update?.();
|
|
1079
|
-
});
|
|
1080
|
-
ctx.setAction("pageUp", () => {
|
|
1081
|
-
setScrollTop((s) => Math.max(0, s - pageSizeRef.current));
|
|
1082
|
-
bump((n) => n + 1);
|
|
1083
|
-
ctx.update?.();
|
|
1084
|
-
});
|
|
1085
|
-
ctx.setAction("pageDown", () => {
|
|
1086
|
-
setScrollTop((s) => Math.min(maxScrollRef.current, s + pageSizeRef.current));
|
|
1087
|
-
bump((n) => n + 1);
|
|
1088
|
-
ctx.update?.();
|
|
1089
|
-
});
|
|
1113
|
+
ctx.setAction("scrollUp", () => applyUserScroll(-1));
|
|
1114
|
+
ctx.setAction("scrollDown", () => applyUserScroll(1));
|
|
1115
|
+
ctx.setAction("pageUp", () => applyUserScroll(-pageSizeRef.current));
|
|
1116
|
+
ctx.setAction("pageDown", () => applyUserScroll(pageSizeRef.current));
|
|
1090
1117
|
return void 0;
|
|
1091
|
-
}, [ctx, bindKeys]);
|
|
1092
|
-
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "");
|
|
1118
|
+
}, [ctx, bindKeys, followBottom]);
|
|
1119
|
+
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "") + (followBottom && following ? " \xB7 follow" : followBottom ? " \xB7 follow off" : "");
|
|
1093
1120
|
const rowNodes = visible.map((line, i) => {
|
|
1094
1121
|
const body = padEndVisible(line, textWidth);
|
|
1095
1122
|
const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? " " : "";
|
|
@@ -1127,6 +1154,7 @@ var init_scrollable_text = __esm({
|
|
|
1127
1154
|
"src/screen/scrollable-text.js"() {
|
|
1128
1155
|
init_components();
|
|
1129
1156
|
init_scrollbar();
|
|
1157
|
+
init_follow_scroll();
|
|
1130
1158
|
init_scrollbar();
|
|
1131
1159
|
h5 = createElement2;
|
|
1132
1160
|
SCROLL_KEYS = [
|
|
@@ -1295,10 +1323,14 @@ __export(screen_exports, {
|
|
|
1295
1323
|
buildBreadcrumb: () => buildBreadcrumb,
|
|
1296
1324
|
buildDetailBreadcrumb: () => buildDetailBreadcrumb,
|
|
1297
1325
|
buildFooter: () => buildFooter,
|
|
1326
|
+
clampScroll: () => clampScroll,
|
|
1298
1327
|
formatBindingKey: () => formatBindingKey,
|
|
1299
1328
|
h: () => createElement3,
|
|
1329
|
+
isScrolledToBottom: () => isScrolledToBottom,
|
|
1300
1330
|
load: () => load,
|
|
1301
1331
|
memo: () => memo,
|
|
1332
|
+
nextScrollAfterContentChange: () => nextScrollAfterContentChange,
|
|
1333
|
+
nextScrollAfterUserMove: () => nextScrollAfterUserMove,
|
|
1302
1334
|
organizeFooterMessages: () => organizeFooterMessages,
|
|
1303
1335
|
scrollbarGlyphs: () => scrollbarGlyphs,
|
|
1304
1336
|
showListScreen: () => showListScreen,
|
|
@@ -1335,6 +1367,7 @@ var init_screen = __esm({
|
|
|
1335
1367
|
init_components();
|
|
1336
1368
|
init_ui_elements();
|
|
1337
1369
|
init_scrollable_text();
|
|
1370
|
+
init_follow_scroll();
|
|
1338
1371
|
init_scrollbar();
|
|
1339
1372
|
init_key_bindings();
|
|
1340
1373
|
init_utils();
|