"use client"; import { Box, type BoxProps, Newline, Text, useInput } from "ink"; import { type ReactNode, useEffect, useState } from "react"; import { useStdoutDimensions } from "../useStdoutDimensions"; interface ScrollListProps extends BoxProps { list: ReactNode[]; } export const ScrollList = ({ list, ...props }: ScrollListProps) => { const [renderLogs, setRenderLogs] = useState(list); const [width, height] = useStdoutDimensions(); const [scrollPos, setScrollPos] = useState(0); const [isRunning, setIsRunning] = useState(false); const [boxHeight, setBoxHeight] = useState(height - 3); useInput((input, key) => { if (key.escape) { setIsRunning(false); setScrollPos(0); } if (input === " " && isRunning) { setIsRunning(false); setScrollPos(0); } if (key.downArrow && scrollPos > 0) { if (key.shift) { setScrollPos(scrollPos - 10); } else { setScrollPos(scrollPos - 1); } } if (key.upArrow && scrollPos < list.length - boxHeight) { if (key.shift) { setScrollPos(scrollPos + 10); } else { setScrollPos(scrollPos + 1); } } }); useEffect(() => { //1 로그가 박스 높이보다 크면 스크롤 위치 조정 //2. scrollPos값에 따라 포커싱 위치 변경하고 pos 활성시 포커싱 위치 고정 if (isRunning) { setScrollPos(scrollPos + 1); return; } if (list.length > boxHeight) { setRenderLogs(list.slice(list.length - boxHeight, list.length)); } else { setRenderLogs(list); } }, [list, isRunning]); useEffect(() => { setBoxHeight(Math.floor(height * 0.9)); }, [height]); useEffect(() => { if (scrollPos > 0) { setRenderLogs(list.slice(list.length - boxHeight - scrollPos, list.length - scrollPos)); setIsRunning(true); } else { setRenderLogs(list.slice(list.length - boxHeight, list.length)); setIsRunning(false); } }, [scrollPos]); return ( {isRunning ? ( <> {renderLogs.slice(0, renderLogs.length - 1).map((log, index) => ( <> {log} ))} scrolling... + {scrollPos} ) : ( <> {renderLogs.map((log, index) => ( <> {log} ))} )} You can use the following shortcuts: * up and down to scroll.{" "} shift to scroll faster. * escape to stop scrolling. ); };