@kud/gh-ink 0.16.0 → 0.16.2
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/index.js +80 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1566,11 +1566,11 @@ var RepoHeaderRow = ({ repo, gap }) => {
|
|
|
1566
1566
|
const fill = Math.max(4, 46 - label.length);
|
|
1567
1567
|
return /* @__PURE__ */ jsx(Box, { marginTop: gap ? 1 : 0, children: /* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + label + "\u2500".repeat(fill) }) });
|
|
1568
1568
|
};
|
|
1569
|
-
var MERGED_HOLD_MS =
|
|
1569
|
+
var MERGED_HOLD_MS = 5e3;
|
|
1570
1570
|
var MERGED_FRAME_MS = 150;
|
|
1571
1571
|
var MERGED_FRAMES = ["\u2726", "\u2727", "\u2736", "\u2727"];
|
|
1572
1572
|
var MERGED_COLOUR = "#A371F7";
|
|
1573
|
-
var TRANSIT_HOLD_MS =
|
|
1573
|
+
var TRANSIT_HOLD_MS = 7e3;
|
|
1574
1574
|
var NO_TRANSIENTS = /* @__PURE__ */ new Map();
|
|
1575
1575
|
var TRANSIT_OUT_FRAMES = ["\u25C9", "\u25CE", "\u25CB", "\xB7"];
|
|
1576
1576
|
var TRANSIT_IN_FRAMES = ["\xB7", "\u25CB", "\u25CE", "\u25C9"];
|
|
@@ -1760,35 +1760,48 @@ var legendLayout = (cols, available) => {
|
|
|
1760
1760
|
if (layoutWidth(stacked) <= available) return stacked;
|
|
1761
1761
|
return [cols];
|
|
1762
1762
|
};
|
|
1763
|
+
var groupLines = (group) => group.flatMap((col, index) => {
|
|
1764
|
+
const cellWidth = cellWidthOf(col);
|
|
1765
|
+
const head = index === 0 ? [] : [{ kind: "gap" }];
|
|
1766
|
+
return [
|
|
1767
|
+
...head,
|
|
1768
|
+
{ kind: "title", text: col.title },
|
|
1769
|
+
...col.rows.map((row) => ({ kind: "row", row, cellWidth }))
|
|
1770
|
+
];
|
|
1771
|
+
});
|
|
1772
|
+
var scrolledPastTitle = (lines, offset) => {
|
|
1773
|
+
let seen = null;
|
|
1774
|
+
for (let i = 0; i <= offset && i < lines.length; i++) {
|
|
1775
|
+
const line = lines[i];
|
|
1776
|
+
if (line.kind === "title") seen = i === offset ? null : line.text;
|
|
1777
|
+
}
|
|
1778
|
+
return seen;
|
|
1779
|
+
};
|
|
1763
1780
|
var LegendGroup = ({
|
|
1764
|
-
|
|
1781
|
+
lines,
|
|
1782
|
+
pinned,
|
|
1765
1783
|
width,
|
|
1766
1784
|
marginRight
|
|
1767
|
-
}) => /* @__PURE__ */
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
Box,
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
/* @__PURE__ */ jsx(Text2, { color: row.color, bold: row.bold, children: row.cell.padEnd(cellWidth) }),
|
|
1778
|
-
/* @__PURE__ */ jsx(Text2, { wrap: "truncate-end", children: row.label })
|
|
1779
|
-
] }, col.title + row.cell + row.label))
|
|
1780
|
-
]
|
|
1781
|
-
},
|
|
1782
|
-
col.title
|
|
1783
|
-
);
|
|
1784
|
-
}) });
|
|
1785
|
+
}) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, marginRight, children: [
|
|
1786
|
+
pinned !== void 0 ? /* @__PURE__ */ jsx(Text2, { bold: true, dimColor: true, children: pinned ?? " " }) : null,
|
|
1787
|
+
lines.map(
|
|
1788
|
+
(line, index) => line.kind === "gap" ? /* @__PURE__ */ jsx(Text2, { children: " " }, index) : line.kind === "title" ? /* @__PURE__ */ jsx(Text2, { bold: true, dimColor: true, children: line.text }, index) : /* @__PURE__ */ jsxs(Box, { children: [
|
|
1789
|
+
/* @__PURE__ */ jsx(Text2, { color: line.row.color, bold: line.row.bold, children: line.row.cell.padEnd(line.cellWidth) }),
|
|
1790
|
+
/* @__PURE__ */ jsx(Text2, { wrap: "truncate-end", children: line.row.label })
|
|
1791
|
+
] }, index)
|
|
1792
|
+
)
|
|
1793
|
+
] });
|
|
1794
|
+
var LEGEND_FOOTNOTE = "Each item lands in the FIRST tab that claims it, so counts are residuals rather than totals.";
|
|
1785
1795
|
var HelpModal = ({
|
|
1786
1796
|
workToggle,
|
|
1787
1797
|
extensions,
|
|
1788
1798
|
hasJira,
|
|
1789
|
-
tabHelp
|
|
1799
|
+
tabHelp,
|
|
1800
|
+
maxRows,
|
|
1801
|
+
scroll = 0,
|
|
1802
|
+
onScrollRange
|
|
1790
1803
|
}) => {
|
|
1791
|
-
const { columns } = useWindowSize();
|
|
1804
|
+
const { columns, rows } = useWindowSize();
|
|
1792
1805
|
const available = Math.max(
|
|
1793
1806
|
20,
|
|
1794
1807
|
columns - FRAME_CHROME_COLS - MODAL_CHROME_COLS
|
|
@@ -1857,6 +1870,28 @@ var HelpModal = ({
|
|
|
1857
1870
|
const groups = legendLayout(cols, available);
|
|
1858
1871
|
const widths = groups.map((g) => Math.min(groupWidth(g), available));
|
|
1859
1872
|
const contentWidth = Math.min(available, layoutWidth(groups));
|
|
1873
|
+
const lines = groups.map(groupLines);
|
|
1874
|
+
const totalRows = Math.max(0, ...lines.map((l) => l.length));
|
|
1875
|
+
const footnoteRows = tabHelp ? Math.ceil(LEGEND_FOOTNOTE.length / Math.max(1, contentWidth)) : 0;
|
|
1876
|
+
const chromeRows = 2 + 1 + 1 + 1;
|
|
1877
|
+
const fitWithin = (extra) => {
|
|
1878
|
+
const body = Math.max(3, (maxRows ?? rows) - chromeRows - extra);
|
|
1879
|
+
return { body, max: Math.max(0, totalRows - body) };
|
|
1880
|
+
};
|
|
1881
|
+
const loose = fitWithin(footnoteRows);
|
|
1882
|
+
const { body: bodyRows, max: maxScroll } = loose.max > 0 ? fitWithin(1) : loose;
|
|
1883
|
+
const offset = Math.min(scroll, maxScroll);
|
|
1884
|
+
const scrollable = maxScroll > 0;
|
|
1885
|
+
const headAligned = scrollable && lines.every((l) => l[offset]?.kind === "title");
|
|
1886
|
+
const pinnedOf = (l) => {
|
|
1887
|
+
const at = l[offset];
|
|
1888
|
+
return headAligned && at?.kind === "title" ? at.text : scrolledPastTitle(l, offset);
|
|
1889
|
+
};
|
|
1890
|
+
const bodyStart = offset + (headAligned ? 1 : 0);
|
|
1891
|
+
const shown = Math.min(totalRows - offset, bodyRows + (headAligned ? 1 : 0));
|
|
1892
|
+
useEffect(() => {
|
|
1893
|
+
onScrollRange?.(maxScroll, bodyRows);
|
|
1894
|
+
}, [maxScroll, bodyRows]);
|
|
1860
1895
|
return /* @__PURE__ */ jsxs(
|
|
1861
1896
|
Box,
|
|
1862
1897
|
{
|
|
@@ -1867,18 +1902,22 @@ var HelpModal = ({
|
|
|
1867
1902
|
paddingX: 1,
|
|
1868
1903
|
width: contentWidth + MODAL_CHROME_COLS,
|
|
1869
1904
|
children: [
|
|
1870
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1906
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", bold: true, children: "Legend" }),
|
|
1907
|
+
scrollable ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: ` ${offset + 1}\u2013${offset + shown} of ${totalRows}` }) : null
|
|
1908
|
+
] }),
|
|
1871
1909
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, width: contentWidth, children: groups.map((group, index) => /* @__PURE__ */ jsx(
|
|
1872
1910
|
LegendGroup,
|
|
1873
1911
|
{
|
|
1874
|
-
|
|
1912
|
+
lines: lines[index].slice(bodyStart, bodyStart + bodyRows),
|
|
1913
|
+
pinned: scrollable ? pinnedOf(lines[index]) : void 0,
|
|
1875
1914
|
width: widths[index],
|
|
1876
1915
|
marginRight: index === groups.length - 1 ? 0 : COL_GAP
|
|
1877
1916
|
},
|
|
1878
1917
|
group[0]?.title ?? index
|
|
1879
1918
|
)) }),
|
|
1880
|
-
tabHelp ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children:
|
|
1881
|
-
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "esc \xB7 ? close" })
|
|
1919
|
+
tabHelp && !scrollable ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: LEGEND_FOOTNOTE }) : null,
|
|
1920
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: scrollable ? "\u2191\u2193 scroll \xB7 esc \xB7 ? close" : "esc \xB7 ? close" })
|
|
1882
1921
|
]
|
|
1883
1922
|
}
|
|
1884
1923
|
);
|
|
@@ -2000,6 +2039,8 @@ var BrowseScreen = ({
|
|
|
2000
2039
|
const [repoFilter, setRepoFilter] = useState(/* @__PURE__ */ new Set());
|
|
2001
2040
|
const [repoPicker, setRepoPicker] = useState(false);
|
|
2002
2041
|
const [help, setHelp] = useState(false);
|
|
2042
|
+
const [helpScroll, setHelpScroll] = useState(0);
|
|
2043
|
+
const [helpRange, setHelpRange] = useState({ max: 0, page: 1 });
|
|
2003
2044
|
const [explain, setExplain] = useState(false);
|
|
2004
2045
|
const filterActive = search != null || repoFilter.size > 0;
|
|
2005
2046
|
const reserveCiRow = ciStatusState != null;
|
|
@@ -2118,10 +2159,18 @@ var BrowseScreen = ({
|
|
|
2118
2159
|
if (hidden) return;
|
|
2119
2160
|
if (key.ctrl || key.meta) return;
|
|
2120
2161
|
if (help) {
|
|
2162
|
+
if (helpRange.max > 0) {
|
|
2163
|
+
const step = (n) => setHelpScroll((s) => Math.min(helpRange.max, Math.max(0, s + n)));
|
|
2164
|
+
if (key.upArrow) return step(-1);
|
|
2165
|
+
if (key.downArrow) return step(1);
|
|
2166
|
+
if (key.pageUp) return step(-helpRange.page);
|
|
2167
|
+
if (key.pageDown) return step(helpRange.page);
|
|
2168
|
+
}
|
|
2121
2169
|
setHelp(false);
|
|
2122
2170
|
return;
|
|
2123
2171
|
}
|
|
2124
2172
|
if (input === "?") {
|
|
2173
|
+
setHelpScroll(0);
|
|
2125
2174
|
setHelp(true);
|
|
2126
2175
|
return;
|
|
2127
2176
|
}
|
|
@@ -2384,7 +2433,10 @@ var BrowseScreen = ({
|
|
|
2384
2433
|
workToggle,
|
|
2385
2434
|
extensions,
|
|
2386
2435
|
hasJira: !!jiraBase,
|
|
2387
|
-
tabHelp
|
|
2436
|
+
tabHelp,
|
|
2437
|
+
maxRows: listHeight,
|
|
2438
|
+
scroll: helpScroll,
|
|
2439
|
+
onScrollRange: (max, page) => setHelpRange({ max, page })
|
|
2388
2440
|
}
|
|
2389
2441
|
) : explain && activeItem && (activeItem.kind === "pr" || activeItem.kind === "issue") ? /* @__PURE__ */ jsx(ExplainModal, { item: activeItem, login }) : repoPicker ? /* @__PURE__ */ jsx(
|
|
2390
2442
|
RepoPicker,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kud/gh-ink",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
4
4
|
"description": "Ink components for rendering GitHub PR review comments and health — controlled, presentation-only, built on @kud/ink-ui and fed by @kud/gh.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|