UNPKG

@farjs/ui

Version:

Terminal UI React.js components library

98 lines (88 loc) 2.37 kB
/** * @typedef {import("@farjs/blessed").Widgets.Events.IKeyEventArg} IKeyEventArg */ import React, { useLayoutEffect, useState } from "react"; import { createListViewport } from "./ListViewport.mjs"; import ListView from "./ListView.mjs"; import ScrollBar from "./ScrollBar.mjs"; const h = React.createElement; /** * @typedef {{ * readonly left: number; * readonly top: number; * readonly width: number; * readonly height: number; * readonly style: import("@farjs/blessed").Widgets.Types.TStyle; * readonly items: readonly string[]; * readonly selected: number; * onAction(index: number): void; * onSelect?(index: number): void; * }} ListBoxProps */ /** * @param {ListBoxProps} props */ const ListBox = (props) => { const { listViewComp, scrollBarComp } = ListBox; const [viewport, setViewport] = useState( createListViewport(props.selected, props.items.length, props.height) ); const selected = viewport.offset + viewport.focused; /** @type {(ch: any, key: IKeyEventArg) => void} */ const onKeypress = (_, key) => { switch (key.full) { case "return": props.onAction(selected); break; default: const vp = viewport.onKeypress(key.full); if (vp) { setViewport(vp); } break; } }; useLayoutEffect(() => { props.onSelect?.call(null, selected); }, [selected]); return h( "button", { left: props.left, top: props.top, width: props.width, height: props.height, onKeypress, }, h(listViewComp, { left: 0, top: 0, width: props.width, height: props.height, items: props.items, viewport, setViewport, style: props.style, onClick: props.onAction, }), viewport.length > viewport.viewLength ? h(scrollBarComp, { left: props.width, top: 0, length: viewport.viewLength, style: props.style, value: viewport.offset, extent: viewport.viewLength, min: 0, max: viewport.length - viewport.viewLength, onChange: (offset) => { setViewport(viewport.updated(offset)); }, }) : null ); }; ListBox.displayName = "ListBox"; ListBox.listViewComp = ListView; ListBox.scrollBarComp = ScrollBar; export default ListBox;