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