playball
Version:
Watch MLB games from the comfort of your terminal
88 lines • 3.06 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useCallback, useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import useKey from "../hooks/useKey.js";
function Grid({
items,
itemHeight,
itemMinWidth,
onSelect
}) {
const containerRef = useRef();
const [size, setSize] = useState([0, 0]);
const [selectedIndex, setSelectedIndex] = useState(0);
const updateSize = () => {
var _containerRef$current, _containerRef$current2;
return setSize([(_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.width, (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.height]);
};
useEffect(updateSize, []);
const pos = [];
let row = 0;
let col = 0;
const numCols = Math.floor(size[0] / itemMinWidth);
const colWidth = Math.floor(size[0] / numCols);
for (let i = 0; i < items.length; i++) {
pos.push({
top: row,
left: col,
width: colWidth,
height: itemHeight
});
col += colWidth;
if (col > size[0] - colWidth) {
col = 0;
row += itemHeight;
}
}
useEffect(() => {
const curr = pos[selectedIndex].top;
const total = pos[pos.length - 1].top;
const perc = Math.round(curr / total * 100);
containerRef.current.setScrollPerc(perc);
}, [pos, selectedIndex]);
useKey(['right', 'l'], useCallback(() => setSelectedIndex(prev => Math.min(prev + 1, items.length - 1)), [items.length]));
useKey(['left', 'h'], useCallback(() => setSelectedIndex(prev => Math.max(prev - 1, 0)), []));
useKey(['down', 'j'], useCallback(() => {
setSelectedIndex(prev => {
const next = prev + numCols;
if (next < items.length) {
return next;
} else {
return prev;
}
});
}, [numCols, items.length]));
useKey(['up', 'k'], useCallback(() => {
setSelectedIndex(prev => {
const next = prev - numCols;
if (next >= 0) {
return next;
} else {
return prev;
}
});
}, [numCols]));
useKey('enter', () => onSelect(selectedIndex));
return /*#__PURE__*/React.createElement("box", {
ref: containerRef,
onResize: updateSize,
width: "100%",
height: "100%",
scrollable: true
}, pos.map((p, idx) => /*#__PURE__*/React.createElement("box", _extends({}, p, {
border: {
type: selectedIndex === idx ? 'line' : 'bg'
},
key: items[idx],
tags: true,
content: items[idx],
wrap: false
}))));
}
Grid.propTypes = {
items: PropTypes.arrayOf(PropTypes.string),
itemHeight: PropTypes.number,
itemMinWidth: PropTypes.number,
onSelect: PropTypes.func
};
export default Grid;