@hhoangphuoc/escape-room-cli
Version:
A CLI for playing AI-generated escape room games. Install globally with: npm install -g @hhoangphuoc/escape-room-cli
43 lines (42 loc) • 1.96 kB
JavaScript
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Box, useInput } from 'ink';
const ScrollableBox = React.forwardRef(({ children, height = 20, // Default height
}, ref) => {
const [scrollPos, setScrollPos] = useState(0);
const childrenArray = React.Children.toArray(children);
const totalItems = childrenArray.length;
const maxScroll = Math.max(0, totalItems - height);
// Auto-scroll to bottom on new content
const prevChildrenLengthRef = useRef(totalItems);
useImperativeHandle(ref, () => ({
scrollToBottom: () => {
setScrollPos(maxScroll);
}
}));
useEffect(() => {
if (totalItems > prevChildrenLengthRef.current) {
setScrollPos(maxScroll);
}
prevChildrenLengthRef.current = totalItems;
}, [totalItems, maxScroll]);
// Handle keyboard scrolling
useInput((_, key) => {
if (key.upArrow) {
setScrollPos(Math.max(0, scrollPos - 1));
}
else if (key.downArrow) {
setScrollPos(Math.min(maxScroll, scrollPos + 1));
}
else if (key.pageUp) {
setScrollPos(Math.max(0, scrollPos - height));
}
else if (key.pageDown) {
setScrollPos(Math.min(maxScroll, scrollPos + height));
}
});
// Calculate which items to show in view
const visibleChildren = childrenArray.slice(scrollPos, scrollPos + height);
return (_jsxs(Box, { flexDirection: "column", children: [visibleChildren, totalItems > height && (_jsx(Box, { marginTop: 1, children: _jsx(Box, { marginRight: 1, children: _jsxs(Box, { children: [_jsx(Box, { marginRight: 1, children: _jsxs(Box, { children: ["Scroll: ", scrollPos + 1, "/", totalItems] }) }), scrollPos > 0 ? '↑' : ' ', scrollPos < maxScroll ? '↓' : ' '] }) }) }))] }));
});
export default ScrollableBox;