@kud/gh-ink 0.65.0 → 0.66.0

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.d.ts CHANGED
@@ -209,6 +209,13 @@ type PrRowProps = {
209
209
  item: GHItem;
210
210
  active: boolean;
211
211
  login?: string;
212
+ /**
213
+ * The selection wash for this frame, resolved by the list — see
214
+ * `selectionBackground` in the inbox. A prop rather than an import because
215
+ * the constant lives next to the inbox's `OVERLAY_BG` and importing the inbox
216
+ * here would cycle back through this module. Absent the row draws no wash.
217
+ */
218
+ selectionBg?: string;
212
219
  /**
213
220
  * Columns available to this row, which is NOT always the frame width: a rail
214
221
  * beside the list takes its share, and a budget that does not know the rail is
@@ -256,6 +263,13 @@ type PrRowProps = {
256
263
  * number into the title.
257
264
  */
258
265
  numberCols?: number;
266
+ /**
267
+ * Whether the row draws its own `❯` gutter. A host that marks the selected
268
+ * stop itself, in a column further left, passes `false` — otherwise the
269
+ * selected row carries two cursors (`❯ ├─ ❯ …`). Hidden, the two columns go
270
+ * to the title rather than standing empty.
271
+ */
272
+ gutter?: boolean;
259
273
  };
260
274
  /**
261
275
  * The trailing block, in reading order: how contested, how big, how recent.
@@ -292,7 +306,7 @@ declare const trailingColumnsOf: (items: readonly GHItem[]) => TrailingColumns;
292
306
  * section of short numbers no longer pays for a long one it does not hold.
293
307
  */
294
308
  declare const numberColumnsOf: (items: readonly GHItem[]) => number;
295
- type LayoutInput = Pick<PrRowProps, "item" | "login" | "cols" | "prefix" | "uniformLabels" | "announcements" | "columns" | "shed" | "numberCols">;
309
+ type LayoutInput = Pick<PrRowProps, "item" | "login" | "cols" | "prefix" | "uniformLabels" | "announcements" | "columns" | "shed" | "numberCols" | "gutter">;
296
310
  /**
297
311
  * Which trailing columns the section has to give up, so that every row gives up
298
312
  * the same ones. Each row is laid out alone and the drops are unioned: if any
@@ -318,7 +332,7 @@ declare const sectionShedOf: (rows: readonly Pick<LayoutInput, "item" | "prefix"
318
332
  * arrival, merge and departure belongs to whoever owns the list, and reaches
319
333
  * the row as `icon`, `motion` and `announcements` after the decisions are made.
320
334
  */
321
- declare const PrRow: ({ item, active, login, cols, icon: iconOverride, prefix, uniformLabels, motion, announcements, columns, shed, numberCols, }: PrRowProps) => React.JSX.Element;
335
+ declare const PrRow: ({ item, active, login, cols, selectionBg, icon: iconOverride, prefix, uniformLabels, motion, announcements, columns, shed, numberCols, gutter, }: PrRowProps) => React.JSX.Element;
322
336
 
323
337
  /**
324
338
  * One state per thing, from a closed set the strip knows how to draw. The host
package/dist/index.js CHANGED
@@ -867,7 +867,8 @@ var layoutOf = ({
867
867
  announcements = [],
868
868
  columns,
869
869
  shed = {},
870
- numberCols
870
+ numberCols,
871
+ gutter = true
871
872
  }) => {
872
873
  const numCols = numberCols ?? numberColumnsOf([item]);
873
874
  const numStr = `#${item.number}`.padEnd(numCols);
@@ -914,7 +915,7 @@ var layoutOf = ({
914
915
  const author = showAuthor && !givingUp.author ? ` by ${item.author}`.length : 0;
915
916
  const pills = announcements.reduce((w, a) => w + 2 + a.label.length, 0);
916
917
  const cell = labelCell();
917
- return 2 + prefix.length + 2 + 2 + numCols + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) + author + block + pills + pillCaps + 4;
918
+ return (gutter ? 2 : 0) + prefix.length + 2 + 2 + numCols + (cell ? 2 + cell.length + 1 : 0) + (givingUp.repo ? 0 : repoLabel.length) + author + block + pills + pillCaps + 4;
918
919
  };
919
920
  const MIN_TITLE = 24;
920
921
  for (const give of [
@@ -950,6 +951,7 @@ var PrRow = ({
950
951
  active,
951
952
  login,
952
953
  cols,
954
+ selectionBg,
953
955
  icon: iconOverride,
954
956
  prefix = "",
955
957
  uniformLabels = [],
@@ -957,7 +959,8 @@ var PrRow = ({
957
959
  announcements = [],
958
960
  columns,
959
961
  shed,
960
- numberCols
962
+ numberCols,
963
+ gutter = true
961
964
  }) => {
962
965
  const backdropped = useBackdropped();
963
966
  const { glyph: healthIcon, color: healthColor2 } = displayFor(item.health);
@@ -988,70 +991,75 @@ var PrRow = ({
988
991
  announcements,
989
992
  columns,
990
993
  shed,
991
- numberCols
994
+ numberCols,
995
+ gutter
992
996
  });
993
- return /* @__PURE__ */ jsxs(Box, { width: cols, children: [
994
- /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
995
- /* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
996
- /* @__PURE__ */ jsx(Text3, { color, bold: true, children: icon + " " }),
997
- /* @__PURE__ */ jsx(Text3, { color: turnColor, bold: turnIcon === "\u2190", children: turnIcon + " " }),
998
- /* @__PURE__ */ jsx(Text3, { color: colors.accent, children: numStr }),
999
- /* @__PURE__ */ jsx(
1000
- Text3,
1001
- {
1002
- bold: active || motion === "arriving",
1003
- dimColor: motion === "departing" || motion === "withdrawn",
1004
- strikethrough: motion === "withdrawn",
1005
- children: truncate(
1006
- item.needsYou?.decision ? item.needsYou.decision : item.title,
1007
- titleMax
1008
- ) + " "
1009
- }
1010
- ),
1011
- labelLabel ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: labelLabel + " " }) : null,
1012
- repoLabel && !givingUp.repo ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: repoLabel }) : null,
1013
- showAuthor && !givingUp.author ? /* @__PURE__ */ jsx(Text3, { dimColor: true, italic: true, children: " by " + item.author }) : null,
1014
- /* @__PURE__ */ jsx(Box, { flexGrow: 1 }),
1015
- block.threads > 0 && !givingUp.threads ? /* @__PURE__ */ jsx(
1016
- Box,
1017
- {
1018
- marginLeft: 2,
1019
- width: block.threads,
1020
- justifyContent: "flex-end",
1021
- flexShrink: 0,
1022
- children: unresolvedLabel ? /* @__PURE__ */ jsx(
1023
- Text3,
1024
- {
1025
- bold: !spokeLast,
1026
- color: spokeLast ? colors.secondary : colors.accent,
1027
- children: unresolvedLabel
1028
- }
1029
- ) : null
1030
- }
1031
- ) : null,
1032
- block.size > 0 && !givingUp.size ? /* @__PURE__ */ jsx(
1033
- Box,
1034
- {
1035
- marginLeft: 2,
1036
- width: block.size,
1037
- justifyContent: "flex-end",
1038
- flexShrink: 0,
1039
- children: sizeParts ? /* @__PURE__ */ jsxs(Text3, { children: [
1040
- /* @__PURE__ */ jsx(Text3, { color: colors.success, children: sizeParts.added }),
1041
- " ",
1042
- /* @__PURE__ */ jsx(Text3, { color: colors.error, children: sizeParts.removed })
1043
- ] }) : null
1044
- }
1045
- ) : null,
1046
- block.age > 0 && !givingUp.age ? /* @__PURE__ */ jsx(Box, { marginLeft: 2, width: block.age, flexShrink: 0, children: agePair ? /* @__PURE__ */ jsxs(Text3, { children: [
1047
- /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: agePair.activity }),
1048
- /* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` (${agePair.lifetime})` })
1049
- ] }) : ageLabel2 ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: ageLabel2 }) : null }) : null,
1050
- backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
1051
- /* @__PURE__ */ jsx(Text3, { children: " " }),
1052
- /* @__PURE__ */ jsx(Pill, { color: a.color, children: a.label })
1053
- ] }, a.label))
1054
- ] });
997
+ return (
998
+ // The wash paints every cell of the fixed-width row — an Ink Box's
999
+ // background covers its full measure, not just the inked cells.
1000
+ /* @__PURE__ */ jsxs(Box, { width: cols, backgroundColor: selectionBg, children: [
1001
+ gutter ? /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }) : null,
1002
+ /* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
1003
+ /* @__PURE__ */ jsx(Text3, { color, bold: true, children: icon + " " }),
1004
+ /* @__PURE__ */ jsx(Text3, { color: turnColor, bold: turnIcon === "\u2190", children: turnIcon + " " }),
1005
+ /* @__PURE__ */ jsx(Text3, { color: colors.accent, children: numStr }),
1006
+ /* @__PURE__ */ jsx(
1007
+ Text3,
1008
+ {
1009
+ bold: active || motion === "arriving",
1010
+ dimColor: motion === "departing" || motion === "withdrawn",
1011
+ strikethrough: motion === "withdrawn",
1012
+ children: truncate(
1013
+ item.needsYou?.decision ? item.needsYou.decision : item.title,
1014
+ titleMax
1015
+ ) + " "
1016
+ }
1017
+ ),
1018
+ labelLabel ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: labelLabel + " " }) : null,
1019
+ repoLabel && !givingUp.repo ? /* @__PURE__ */ jsx(Text3, { dimColor: true, children: repoLabel }) : null,
1020
+ showAuthor && !givingUp.author ? /* @__PURE__ */ jsx(Text3, { dimColor: true, italic: true, children: " by " + item.author }) : null,
1021
+ /* @__PURE__ */ jsx(Box, { flexGrow: 1 }),
1022
+ block.threads > 0 && !givingUp.threads ? /* @__PURE__ */ jsx(
1023
+ Box,
1024
+ {
1025
+ marginLeft: 2,
1026
+ width: block.threads,
1027
+ justifyContent: "flex-end",
1028
+ flexShrink: 0,
1029
+ children: unresolvedLabel ? /* @__PURE__ */ jsx(
1030
+ Text3,
1031
+ {
1032
+ bold: !spokeLast,
1033
+ color: spokeLast ? colors.secondary : colors.accent,
1034
+ children: unresolvedLabel
1035
+ }
1036
+ ) : null
1037
+ }
1038
+ ) : null,
1039
+ block.size > 0 && !givingUp.size ? /* @__PURE__ */ jsx(
1040
+ Box,
1041
+ {
1042
+ marginLeft: 2,
1043
+ width: block.size,
1044
+ justifyContent: "flex-end",
1045
+ flexShrink: 0,
1046
+ children: sizeParts ? /* @__PURE__ */ jsxs(Text3, { children: [
1047
+ /* @__PURE__ */ jsx(Text3, { color: colors.success, children: sizeParts.added }),
1048
+ " ",
1049
+ /* @__PURE__ */ jsx(Text3, { color: colors.error, children: sizeParts.removed })
1050
+ ] }) : null
1051
+ }
1052
+ ) : null,
1053
+ block.age > 0 && !givingUp.age ? /* @__PURE__ */ jsx(Box, { marginLeft: 2, width: block.age, flexShrink: 0, children: agePair ? /* @__PURE__ */ jsxs(Text3, { children: [
1054
+ /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: agePair.activity }),
1055
+ /* @__PURE__ */ jsx(Text3, { dimColor: true, children: ` (${agePair.lifetime})` })
1056
+ ] }) : ageLabel2 ? /* @__PURE__ */ jsx(Text3, { color: colors.secondary, children: ageLabel2 }) : null }) : null,
1057
+ backdropped ? null : announcements.map((a) => /* @__PURE__ */ jsxs(React2.Fragment, { children: [
1058
+ /* @__PURE__ */ jsx(Text3, { children: " " }),
1059
+ /* @__PURE__ */ jsx(Pill, { color: a.color, children: a.label })
1060
+ ] }, a.label))
1061
+ ] })
1062
+ );
1055
1063
  };
1056
1064
  var stripGlyph = (state) => {
1057
1065
  switch (state) {
@@ -1850,6 +1858,11 @@ var COLS = (process.stdout.columns ?? 120) - FRAME_CHROME_COLS;
1850
1858
  var MODAL_CHROME_COLS = 2 + 1 * 2;
1851
1859
  var ROW_MAX_COLS = 140;
1852
1860
  var OVERLAY_BG = "#22222e";
1861
+ var SELECTION_BG = "#16161f";
1862
+ var selectionBackground = (active, backdropped) => active && !backdropped ? SELECTION_BG : void 0;
1863
+ var taskKeyStyle = (active) => ({
1864
+ bold: active
1865
+ });
1853
1866
  var workCount = (s) => {
1854
1867
  let n = 0;
1855
1868
  for (let i = 0; i < s.items.length; i++) {
@@ -2316,12 +2329,14 @@ var FENCE_COLS = 46;
2316
2329
  var RepoHeaderRow = ({
2317
2330
  repo,
2318
2331
  gap,
2319
- active
2332
+ active,
2333
+ cols,
2334
+ selectionBg
2320
2335
  }) => {
2321
2336
  const label = `\u2500\u2500 ${repo} `;
2322
2337
  const fill = Math.max(4, FENCE_COLS - label.length);
2323
2338
  const rule = "\u2500".repeat(fill);
2324
- return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
2339
+ return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, width: cols, backgroundColor: selectionBg, children: [
2325
2340
  /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
2326
2341
  /* @__PURE__ */ jsx(Text3, { dimColor: !active, children: "\u2500\u2500 " }),
2327
2342
  /* @__PURE__ */ jsx(
@@ -2393,27 +2408,37 @@ var ItemRow = ({
2393
2408
  numberCols
2394
2409
  }) => {
2395
2410
  const backdropped = useBackdropped();
2411
+ const selBg = selectionBackground(active, backdropped);
2396
2412
  const transient = leaving ? "out" : refreshMark;
2397
2413
  const transitFrame = Math.floor(sparkFrame / TRANSIT_FRAME_TICKS);
2398
2414
  const rampAt = (len) => rampFrame(len, transitFrame, transitAt);
2399
2415
  const farewellLabel = leaving ? TRANSIT_LABEL.out : "";
2400
2416
  if (item.kind === "repo-header")
2401
- return /* @__PURE__ */ jsx(RepoHeaderRow, { repo: item.repo, gap: gap ?? false, active });
2417
+ return /* @__PURE__ */ jsx(
2418
+ RepoHeaderRow,
2419
+ {
2420
+ repo: item.repo,
2421
+ gap: gap ?? false,
2422
+ active,
2423
+ cols,
2424
+ selectionBg: selBg
2425
+ }
2426
+ );
2402
2427
  if (item.kind === "subgroup-header")
2403
- return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
2428
+ return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, width: cols, backgroundColor: selBg, children: [
2404
2429
  /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
2405
2430
  /* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: true, children: "\xBB " }),
2406
2431
  /* @__PURE__ */ jsx(Text3, { bold: true, children: item.label })
2407
2432
  ] });
2408
2433
  if (item.kind === "show-more")
2409
- return /* @__PURE__ */ jsxs(Box, { children: [
2434
+ return /* @__PURE__ */ jsxs(Box, { width: cols, backgroundColor: selBg, children: [
2410
2435
  /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
2411
2436
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
2412
2437
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: active ? "\u21B5 " : " " }),
2413
2438
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: `+${item.hidden.length} more` })
2414
2439
  ] });
2415
2440
  if (item.kind === "show-less")
2416
- return /* @__PURE__ */ jsxs(Box, { children: [
2441
+ return /* @__PURE__ */ jsxs(Box, { width: cols, backgroundColor: selBg, children: [
2417
2442
  /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
2418
2443
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
2419
2444
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: active ? "\u21B5 " : " " }),
@@ -2426,13 +2451,13 @@ var ItemRow = ({
2426
2451
  1,
2427
2452
  cols - item.key.length - note.length - (item.pill ? pillWidth(item.pill) + 1 : 0) - (farewellLabel ? pillWidth(farewellLabel) + 2 : 0) - prefix.length - (markerCols > 0 ? markerCols + 1 : 0) - 12
2428
2453
  );
2429
- return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, children: [
2454
+ return /* @__PURE__ */ jsxs(Box, { marginTop: gap ? 1 : 0, width: cols, backgroundColor: selBg, children: [
2430
2455
  /* @__PURE__ */ jsx(Text3, { color: colors.info, children: active ? "\u276F " : " " }),
2431
2456
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: prefix }),
2432
2457
  /* @__PURE__ */ jsx(Text3, { dimColor: true, children: parent ? "\u252C " : " " }),
2433
2458
  /* @__PURE__ */ jsx(Text3, { bold: true, color: transient ? TRANSIT_COLOUR[transient] : void 0, children: transitIcon + " " }),
2434
2459
  markerCols > 0 ? /* @__PURE__ */ jsx(Text3, { color: item.markerColor, children: (item.marker ?? "").padEnd(markerCols) + " " }) : null,
2435
- /* @__PURE__ */ jsx(Text3, { color: colors.accent, bold: active, children: item.key + " " }),
2460
+ /* @__PURE__ */ jsx(Text3, { ...taskKeyStyle(active), children: item.key + " " }),
2436
2461
  /* @__PURE__ */ jsx(
2437
2462
  Text3,
2438
2463
  {
@@ -2480,6 +2505,7 @@ var ItemRow = ({
2480
2505
  active,
2481
2506
  login,
2482
2507
  cols,
2508
+ selectionBg: selBg,
2483
2509
  prefix,
2484
2510
  uniformLabels,
2485
2511
  columns,
@@ -3728,7 +3754,7 @@ var BrowseScreen = ({
3728
3754
  prefix: treePrefix(section.items, viewStart + i),
3729
3755
  parent: item.kind === "task" && depthOf(section.items[viewStart + i + 1]) > depthOf(item),
3730
3756
  sparkFrame,
3731
- cols: item.kind === "pr" || item.kind === "issue" ? rowCols : listCols,
3757
+ cols: item.kind === "pr" || item.kind === "issue" || item.kind === "repo-header" || item.kind === "subgroup-header" || item.kind === "task" || item.kind === "show-more" || item.kind === "show-less" ? rowCols : listCols,
3732
3758
  markerCols,
3733
3759
  uniformLabels,
3734
3760
  columns: trailingColumns,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kud/gh-ink",
3
- "version": "0.65.0",
3
+ "version": "0.66.0",
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",
@@ -50,7 +50,7 @@
50
50
  "dependencies": {
51
51
  "@kud/gh": "0.19.0",
52
52
  "@kud/gh-workflow": "0.14.0",
53
- "@kud/ink-ui": "0.31.0",
53
+ "@kud/ink-ui": "0.33.0",
54
54
  "zx": "8.8.5"
55
55
  },
56
56
  "devDependencies": {