@kud/gh-ink 0.16.1 → 0.16.3
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 +81 -28
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1644,7 +1644,8 @@ var ItemRow = ({
|
|
|
1644
1644
|
const { glyph: healthIcon, color: healthColor2 } = healthDisplay[item.health];
|
|
1645
1645
|
const icon = merged ? MERGED_FRAMES[sparkFrame % MERGED_FRAMES.length] : transient === "out" ? TRANSIT_OUT_FRAMES[sparkFrame % TRANSIT_OUT_FRAMES.length] : transient === "in" ? TRANSIT_IN_FRAMES[sparkFrame % TRANSIT_IN_FRAMES.length] : healthIcon;
|
|
1646
1646
|
const color = merged ? MERGED_COLOUR : transient ? TRANSIT_COLOUR[transient] : healthColor2;
|
|
1647
|
-
const
|
|
1647
|
+
const spokeLast = !!login && !!item.lastActor && item.lastActor === login;
|
|
1648
|
+
const [turnIcon, turnColor] = !login || !item.lastActor ? [" ", "white"] : spokeLast ? ["\u2192", "#888888"] : ["\u2190", "#FF8700"];
|
|
1648
1649
|
const numStr = `#${item.number}`.padEnd(7);
|
|
1649
1650
|
const showAuthor = !!item.author && item.author !== login;
|
|
1650
1651
|
const unresolvedLabel = item.unresolved > 0 ? `\uF086 ${item.unresolved}` : "";
|
|
@@ -1677,7 +1678,7 @@ var ItemRow = ({
|
|
|
1677
1678
|
}
|
|
1678
1679
|
),
|
|
1679
1680
|
repoLabel ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: repoLabel }) : null,
|
|
1680
|
-
unresolvedLabel ? /* @__PURE__ */ jsx(Text2, { bold:
|
|
1681
|
+
unresolvedLabel ? /* @__PURE__ */ jsx(Text2, { bold: !spokeLast, color: spokeLast ? "#888888" : "#FF8700", children: " " + unresolvedLabel }) : null,
|
|
1681
1682
|
showAuthor ? /* @__PURE__ */ jsx(Text2, { dimColor: true, italic: true, children: " by " + item.author }) : null,
|
|
1682
1683
|
ageLabel ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: " " + ageLabel }) : null,
|
|
1683
1684
|
mergedLabel ? /* @__PURE__ */ jsx(Text2, { bold: true, color: MERGED_COLOUR, children: " " + mergedLabel }) : null,
|
|
@@ -1760,35 +1761,48 @@ var legendLayout = (cols, available) => {
|
|
|
1760
1761
|
if (layoutWidth(stacked) <= available) return stacked;
|
|
1761
1762
|
return [cols];
|
|
1762
1763
|
};
|
|
1764
|
+
var groupLines = (group) => group.flatMap((col, index) => {
|
|
1765
|
+
const cellWidth = cellWidthOf(col);
|
|
1766
|
+
const head = index === 0 ? [] : [{ kind: "gap" }];
|
|
1767
|
+
return [
|
|
1768
|
+
...head,
|
|
1769
|
+
{ kind: "title", text: col.title },
|
|
1770
|
+
...col.rows.map((row) => ({ kind: "row", row, cellWidth }))
|
|
1771
|
+
];
|
|
1772
|
+
});
|
|
1773
|
+
var scrolledPastTitle = (lines, offset) => {
|
|
1774
|
+
let seen = null;
|
|
1775
|
+
for (let i = 0; i <= offset && i < lines.length; i++) {
|
|
1776
|
+
const line = lines[i];
|
|
1777
|
+
if (line.kind === "title") seen = i === offset ? null : line.text;
|
|
1778
|
+
}
|
|
1779
|
+
return seen;
|
|
1780
|
+
};
|
|
1763
1781
|
var LegendGroup = ({
|
|
1764
|
-
|
|
1782
|
+
lines,
|
|
1783
|
+
pinned,
|
|
1765
1784
|
width,
|
|
1766
1785
|
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
|
-
}) });
|
|
1786
|
+
}) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width, marginRight, children: [
|
|
1787
|
+
pinned !== void 0 ? /* @__PURE__ */ jsx(Text2, { bold: true, dimColor: true, children: pinned ?? " " }) : null,
|
|
1788
|
+
lines.map(
|
|
1789
|
+
(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: [
|
|
1790
|
+
/* @__PURE__ */ jsx(Text2, { color: line.row.color, bold: line.row.bold, children: line.row.cell.padEnd(line.cellWidth) }),
|
|
1791
|
+
/* @__PURE__ */ jsx(Text2, { wrap: "truncate-end", children: line.row.label })
|
|
1792
|
+
] }, index)
|
|
1793
|
+
)
|
|
1794
|
+
] });
|
|
1795
|
+
var LEGEND_FOOTNOTE = "Each item lands in the FIRST tab that claims it, so counts are residuals rather than totals.";
|
|
1785
1796
|
var HelpModal = ({
|
|
1786
1797
|
workToggle,
|
|
1787
1798
|
extensions,
|
|
1788
1799
|
hasJira,
|
|
1789
|
-
tabHelp
|
|
1800
|
+
tabHelp,
|
|
1801
|
+
maxRows,
|
|
1802
|
+
scroll = 0,
|
|
1803
|
+
onScrollRange
|
|
1790
1804
|
}) => {
|
|
1791
|
-
const { columns } = useWindowSize();
|
|
1805
|
+
const { columns, rows } = useWindowSize();
|
|
1792
1806
|
const available = Math.max(
|
|
1793
1807
|
20,
|
|
1794
1808
|
columns - FRAME_CHROME_COLS - MODAL_CHROME_COLS
|
|
@@ -1857,6 +1871,28 @@ var HelpModal = ({
|
|
|
1857
1871
|
const groups = legendLayout(cols, available);
|
|
1858
1872
|
const widths = groups.map((g) => Math.min(groupWidth(g), available));
|
|
1859
1873
|
const contentWidth = Math.min(available, layoutWidth(groups));
|
|
1874
|
+
const lines = groups.map(groupLines);
|
|
1875
|
+
const totalRows = Math.max(0, ...lines.map((l) => l.length));
|
|
1876
|
+
const footnoteRows = tabHelp ? Math.ceil(LEGEND_FOOTNOTE.length / Math.max(1, contentWidth)) : 0;
|
|
1877
|
+
const chromeRows = 2 + 1 + 1 + 1;
|
|
1878
|
+
const fitWithin = (extra) => {
|
|
1879
|
+
const body = Math.max(3, (maxRows ?? rows) - chromeRows - extra);
|
|
1880
|
+
return { body, max: Math.max(0, totalRows - body) };
|
|
1881
|
+
};
|
|
1882
|
+
const loose = fitWithin(footnoteRows);
|
|
1883
|
+
const { body: bodyRows, max: maxScroll } = loose.max > 0 ? fitWithin(1) : loose;
|
|
1884
|
+
const offset = Math.min(scroll, maxScroll);
|
|
1885
|
+
const scrollable = maxScroll > 0;
|
|
1886
|
+
const headAligned = scrollable && lines.every((l) => l[offset]?.kind === "title");
|
|
1887
|
+
const pinnedOf = (l) => {
|
|
1888
|
+
const at = l[offset];
|
|
1889
|
+
return headAligned && at?.kind === "title" ? at.text : scrolledPastTitle(l, offset);
|
|
1890
|
+
};
|
|
1891
|
+
const bodyStart = offset + (headAligned ? 1 : 0);
|
|
1892
|
+
const shown = Math.min(totalRows - offset, bodyRows + (headAligned ? 1 : 0));
|
|
1893
|
+
useEffect(() => {
|
|
1894
|
+
onScrollRange?.(maxScroll, bodyRows);
|
|
1895
|
+
}, [maxScroll, bodyRows]);
|
|
1860
1896
|
return /* @__PURE__ */ jsxs(
|
|
1861
1897
|
Box,
|
|
1862
1898
|
{
|
|
@@ -1867,18 +1903,22 @@ var HelpModal = ({
|
|
|
1867
1903
|
paddingX: 1,
|
|
1868
1904
|
width: contentWidth + MODAL_CHROME_COLS,
|
|
1869
1905
|
children: [
|
|
1870
|
-
/* @__PURE__ */
|
|
1906
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1907
|
+
/* @__PURE__ */ jsx(Text2, { color: "cyan", bold: true, children: "Legend" }),
|
|
1908
|
+
scrollable ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: ` ${offset + 1}\u2013${offset + shown} of ${totalRows}` }) : null
|
|
1909
|
+
] }),
|
|
1871
1910
|
/* @__PURE__ */ jsx(Box, { marginTop: 1, width: contentWidth, children: groups.map((group, index) => /* @__PURE__ */ jsx(
|
|
1872
1911
|
LegendGroup,
|
|
1873
1912
|
{
|
|
1874
|
-
|
|
1913
|
+
lines: lines[index].slice(bodyStart, bodyStart + bodyRows),
|
|
1914
|
+
pinned: scrollable ? pinnedOf(lines[index]) : void 0,
|
|
1875
1915
|
width: widths[index],
|
|
1876
1916
|
marginRight: index === groups.length - 1 ? 0 : COL_GAP
|
|
1877
1917
|
},
|
|
1878
1918
|
group[0]?.title ?? index
|
|
1879
1919
|
)) }),
|
|
1880
|
-
tabHelp ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children:
|
|
1881
|
-
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: "esc \xB7 ? close" })
|
|
1920
|
+
tabHelp && !scrollable ? /* @__PURE__ */ jsx(Text2, { dimColor: true, children: LEGEND_FOOTNOTE }) : null,
|
|
1921
|
+
/* @__PURE__ */ jsx(Text2, { dimColor: true, children: scrollable ? "\u2191\u2193 scroll \xB7 esc \xB7 ? close" : "esc \xB7 ? close" })
|
|
1882
1922
|
]
|
|
1883
1923
|
}
|
|
1884
1924
|
);
|
|
@@ -2000,6 +2040,8 @@ var BrowseScreen = ({
|
|
|
2000
2040
|
const [repoFilter, setRepoFilter] = useState(/* @__PURE__ */ new Set());
|
|
2001
2041
|
const [repoPicker, setRepoPicker] = useState(false);
|
|
2002
2042
|
const [help, setHelp] = useState(false);
|
|
2043
|
+
const [helpScroll, setHelpScroll] = useState(0);
|
|
2044
|
+
const [helpRange, setHelpRange] = useState({ max: 0, page: 1 });
|
|
2003
2045
|
const [explain, setExplain] = useState(false);
|
|
2004
2046
|
const filterActive = search != null || repoFilter.size > 0;
|
|
2005
2047
|
const reserveCiRow = ciStatusState != null;
|
|
@@ -2118,10 +2160,18 @@ var BrowseScreen = ({
|
|
|
2118
2160
|
if (hidden) return;
|
|
2119
2161
|
if (key.ctrl || key.meta) return;
|
|
2120
2162
|
if (help) {
|
|
2163
|
+
if (helpRange.max > 0) {
|
|
2164
|
+
const step = (n) => setHelpScroll((s) => Math.min(helpRange.max, Math.max(0, s + n)));
|
|
2165
|
+
if (key.upArrow) return step(-1);
|
|
2166
|
+
if (key.downArrow) return step(1);
|
|
2167
|
+
if (key.pageUp) return step(-helpRange.page);
|
|
2168
|
+
if (key.pageDown) return step(helpRange.page);
|
|
2169
|
+
}
|
|
2121
2170
|
setHelp(false);
|
|
2122
2171
|
return;
|
|
2123
2172
|
}
|
|
2124
2173
|
if (input === "?") {
|
|
2174
|
+
setHelpScroll(0);
|
|
2125
2175
|
setHelp(true);
|
|
2126
2176
|
return;
|
|
2127
2177
|
}
|
|
@@ -2384,7 +2434,10 @@ var BrowseScreen = ({
|
|
|
2384
2434
|
workToggle,
|
|
2385
2435
|
extensions,
|
|
2386
2436
|
hasJira: !!jiraBase,
|
|
2387
|
-
tabHelp
|
|
2437
|
+
tabHelp,
|
|
2438
|
+
maxRows: listHeight,
|
|
2439
|
+
scroll: helpScroll,
|
|
2440
|
+
onScrollRange: (max, page) => setHelpRange({ max, page })
|
|
2388
2441
|
}
|
|
2389
2442
|
) : explain && activeItem && (activeItem.kind === "pr" || activeItem.kind === "issue") ? /* @__PURE__ */ jsx(ExplainModal, { item: activeItem, login }) : repoPicker ? /* @__PURE__ */ jsx(
|
|
2390
2443
|
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.3",
|
|
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",
|