@kud/gh-ink 0.75.0 → 0.75.1

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
@@ -217,6 +217,7 @@ type FocusSlot = {
217
217
  };
218
218
  };
219
219
  declare const FOCUS_MARK = "\uDB81\uDCFE";
220
+ declare const FOCUS_JUMP_KEY = "g";
220
221
  declare const DEFAULT_FOCUS_LABEL = "focus";
221
222
  declare const DEFAULT_FOCUS_EMPTY = "nothing to focus on";
222
223
  /**
@@ -256,7 +257,7 @@ declare const focusRefColor: (focus: Pick<FocusSlot, "ref" | "refColor">) => str
256
257
  * with nothing to point at. Either prop (`label`/`empty`) reserves the row;
257
258
  * with neither and no focus value the caller draws nothing at all.
258
259
  */
259
- declare const FocusSlotLine: ({ focus, label, empty, width, }: {
260
+ declare const FocusSlotLine: ({ focus, label, empty, width, jumpKey, }: {
260
261
  /** `undefined` while the first answer is out; `null` when it came back empty. */
261
262
  focus: FocusSlot | null | undefined;
262
263
  /** What to call the row. The host's word; defaults to `focus`. */
@@ -265,6 +266,12 @@ declare const FocusSlotLine: ({ focus, label, empty, width, }: {
265
266
  empty?: string;
266
267
  /** Columns the row may use. */
267
268
  width: number;
269
+ /**
270
+ * The key that jumps to the focus row, drawn as a quiet hint after the
271
+ * reason. Ready rows only: loading and empty have no row to jump to, so
272
+ * they never draw it even when it is set.
273
+ */
274
+ jumpKey?: string;
268
275
  }) => React.JSX.Element;
269
276
 
270
277
  /**
@@ -1124,4 +1131,4 @@ declare const matchesFilter: (repo: string, filter: RepoFilter) => boolean;
1124
1131
  */
1125
1132
  declare const parsePatterns: (value: string) => string[];
1126
1133
 
1127
- export { type Action, type ActionGroup, ActionMenu, App, COLS, type ChromeHints, type ChromeSpec, type ChromeState, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, DEFAULT_FOCUS_EMPTY, DEFAULT_FOCUS_LABEL, type DetailContext, type ExplainSection, type ExtensionTarget, FOCUS_MARK, type FocusGutter, type FocusSlot, FocusSlotLine, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraAvailableTransition, type JiraTransition, type JiraTransitionsFor, type LiveLabel, LookupMiss, MIN_SIDEBAR_COLS, type MenuGap, type MenuRow, PrRow, type PrRowProps, type Rails, type RepoFilter, type RowAnnouncement, type RowMotion, SIDEBAR_COLS, type SettledResult, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, type TabForStatus, type TrailingColumns, type TrailingShed, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, focusCellFor, focusRefColor, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, isMenuGap, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, menuRowsOf, menuTone, moveCursor, numberColumnsOf, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, useChrome, windowCount, withHeaders, withoutItem, workCount, writeCache };
1134
+ export { type Action, type ActionGroup, ActionMenu, App, COLS, type ChromeHints, type ChromeSpec, type ChromeState, CiStatusLine, type CiStatusState, type Command, CommentsPanel, type CommentsPanelProps, DEFAULT_FOCUS_EMPTY, DEFAULT_FOCUS_LABEL, type DetailContext, type ExplainSection, type ExtensionTarget, FOCUS_JUMP_KEY, FOCUS_MARK, type FocusGutter, type FocusSlot, FocusSlotLine, HealthPanel, type HealthPanelProps, type InboxBudget, type InboxExtension, type JiraAvailableTransition, type JiraTransition, type JiraTransitionsFor, type LiveLabel, LookupMiss, MIN_SIDEBAR_COLS, type MenuGap, type MenuRow, PrRow, type PrRowProps, type Rails, type RepoFilter, type RowAnnouncement, type RowMotion, SIDEBAR_COLS, type SettledResult, SidePanel, type Sidebar, type SidebarRow, type StatusStrip, StatusStripLine, type StripItem, type StripState, type StripStatusState, type TabForStatus, type TrailingColumns, type TrailingShed, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, focusCellFor, focusRefColor, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, isMenuGap, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, menuRowsOf, menuTone, moveCursor, numberColumnsOf, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, useChrome, windowCount, withHeaders, withoutItem, workCount, writeCache };
package/dist/index.js CHANGED
@@ -1694,6 +1694,7 @@ var failureNotice = (failed) => {
1694
1694
  return `\u2717 Couldn't ${newest.action} ${newest.label}: ${newest.failure?.reason ?? "no reason reported"}${more} w restore`;
1695
1695
  };
1696
1696
  var FOCUS_MARK = "\u{F04FE}";
1697
+ var FOCUS_JUMP_KEY = "g";
1697
1698
  var DEFAULT_FOCUS_LABEL = "focus";
1698
1699
  var DEFAULT_FOCUS_EMPTY = "nothing to focus on";
1699
1700
  var focusCellFor = (focus, url) => {
@@ -1703,23 +1704,34 @@ var focusCellFor = (focus, url) => {
1703
1704
  };
1704
1705
  var focusRefColor = (focus) => focus.refColor ?? (focus.ref.startsWith("#") ? colors.accent : colors.ticket);
1705
1706
  var cells = (s) => [...s].length;
1706
- var titleBudgetOf = (focus, label, width) => {
1707
+ var titleBudgetOf = (focus, label, width, jumpKey) => {
1708
+ const hint = jumpKey ? jumpKey : void 0;
1707
1709
  const mark = focus.mark ?? FOCUS_MARK;
1708
1710
  const head = 2 + cells(mark) + 1 + cells(label) + 2 + (focus.marker ? cells(focus.marker) + 1 : 0) + cells(focus.ref) + 2;
1711
+ const hintCells = hint ? 3 + cells(hint) + 5 : 0;
1709
1712
  const tail = 3 + cells(focus.reason);
1710
- const titleMax = width - head - tail;
1713
+ const titleMax = width - head - tail - hintCells;
1711
1714
  if (titleMax >= 1)
1712
- return { title: truncate(focus.title, titleMax), reason: focus.reason };
1715
+ return { title: truncate(focus.title, titleMax), reason: focus.reason, hint };
1716
+ const reasonMax = width - head - 3 - 1 - hintCells;
1717
+ if (hint === void 0 || reasonMax >= 1)
1718
+ return {
1719
+ title: "",
1720
+ reason: truncate(focus.reason, Math.max(0, width - head - 3 - 1 - hintCells)),
1721
+ hint
1722
+ };
1713
1723
  return {
1714
1724
  title: "",
1715
- reason: truncate(focus.reason, Math.max(0, width - head - 3 - 1))
1725
+ reason: truncate(focus.reason, Math.max(0, width - head - 3 - 1)),
1726
+ hint: void 0
1716
1727
  };
1717
1728
  };
1718
1729
  var FocusSlotLine = ({
1719
1730
  focus,
1720
1731
  label = DEFAULT_FOCUS_LABEL,
1721
1732
  empty = DEFAULT_FOCUS_EMPTY,
1722
- width
1733
+ width,
1734
+ jumpKey
1723
1735
  }) => {
1724
1736
  if (focus === void 0)
1725
1737
  return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
@@ -1732,7 +1744,7 @@ var FocusSlotLine = ({
1732
1744
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: `${label} ${empty}` })
1733
1745
  ] });
1734
1746
  const mark = focus.mark ?? FOCUS_MARK;
1735
- const { title, reason } = titleBudgetOf(focus, label, width);
1747
+ const { title, reason, hint } = titleBudgetOf(focus, label, width, jumpKey);
1736
1748
  return /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
1737
1749
  /* @__PURE__ */ jsx(Text, { children: " " }),
1738
1750
  /* @__PURE__ */ jsx(Text, { color: focus.markColor ?? colors.accent, bold: true, children: `${mark} ` }),
@@ -1740,7 +1752,12 @@ var FocusSlotLine = ({
1740
1752
  focus.marker ? /* @__PURE__ */ jsx(Text, { children: `${focus.marker} ` }) : null,
1741
1753
  /* @__PURE__ */ jsx(Text, { color: focusRefColor(focus), bold: true, children: `${focus.ref} ` }),
1742
1754
  /* @__PURE__ */ jsx(Text, { bold: true, children: title }),
1743
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${reason}` })
1755
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: ` ${reason}` }),
1756
+ hint ? /* @__PURE__ */ jsxs(Fragment, { children: [
1757
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " " }),
1758
+ /* @__PURE__ */ jsx(Text, { color: colors.accent, bold: true, children: hint }),
1759
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: " jump" })
1760
+ ] }) : null
1744
1761
  ] });
1745
1762
  };
1746
1763
  var quietly = $({ quiet: true });
@@ -3324,7 +3341,7 @@ var HelpModal = ({
3324
3341
  ["f", "filter by repo"],
3325
3342
  ["r", "refresh"],
3326
3343
  ["w", "restore a change that failed"],
3327
- ...hasFocus ? [["g", "jump to focus"]] : [],
3344
+ ...hasFocus ? [[FOCUS_JUMP_KEY, "jump to focus"]] : [],
3328
3345
  ...extensionLegend(extensions),
3329
3346
  ["?", "this help"],
3330
3347
  ["q", "quit"]
@@ -3969,7 +3986,7 @@ var BrowseScreen = ({
3969
3986
  onRefresh?.();
3970
3987
  return;
3971
3988
  }
3972
- if (input === "g" && focus) {
3989
+ if (input === FOCUS_JUMP_KEY && focus) {
3973
3990
  const tabId = focus.target.tab;
3974
3991
  const at = localSections.findIndex((s) => s.id === tabId);
3975
3992
  if (at === -1) return;
@@ -4497,7 +4514,8 @@ var BrowseScreen = ({
4497
4514
  focus,
4498
4515
  label: focusLabel,
4499
4516
  empty: focusEmpty,
4500
- width: COLS
4517
+ width: COLS,
4518
+ jumpKey: FOCUS_JUMP_KEY
4501
4519
  }
4502
4520
  ) : null,
4503
4521
  skippedForBudget ? /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
@@ -4750,6 +4768,7 @@ var App = ({
4750
4768
  return sameCiStatusState(prev, next) ? prev : next;
4751
4769
  });
4752
4770
  const hasStrip = !!stripFetcher;
4771
+ const hasFocusSlot = focusLabel !== void 0 || focusEmpty !== void 0;
4753
4772
  const [stripState, setStripState] = useState({
4754
4773
  kind: "loading"
4755
4774
  });
@@ -5168,7 +5187,7 @@ var App = ({
5168
5187
  width: COLS
5169
5188
  }
5170
5189
  ) : null,
5171
- focusLabel !== void 0 || focusEmpty !== void 0 ? /* @__PURE__ */ jsx(
5190
+ hasFocusSlot ? /* @__PURE__ */ jsx(
5172
5191
  FocusSlotLine,
5173
5192
  {
5174
5193
  focus: void 0,
@@ -5181,7 +5200,10 @@ var App = ({
5181
5200
  Box,
5182
5201
  {
5183
5202
  flexDirection: "column",
5184
- minHeight: Math.max(5, rows - 6 - (hasCiStatus ? 2 : 0)),
5203
+ minHeight: Math.max(
5204
+ 5,
5205
+ rows - 6 - (hasCiStatus ? 2 : 0) - (hasStrip ? 2 : 0) - (hasFocusSlot ? 2 : 0)
5206
+ ),
5185
5207
  children: state.phase === "loading" ? /* @__PURE__ */ jsx(LoadingScreen, { label: `Fetching ${title}\u2026` }) : /* @__PURE__ */ jsx(
5186
5208
  NoRowsScreen,
5187
5209
  {
@@ -5340,4 +5362,4 @@ var matchesFilter = (repo, filter) => {
5340
5362
  };
5341
5363
  var parsePatterns = (value) => value.split(",").map((p) => p.trim()).filter(Boolean);
5342
5364
 
5343
- export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, DEFAULT_FOCUS_EMPTY, DEFAULT_FOCUS_LABEL, FOCUS_MARK, FocusSlotLine, HealthPanel, LookupMiss, MIN_SIDEBAR_COLS, PrRow, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, focusCellFor, focusRefColor, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, isMenuGap, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, menuRowsOf, menuTone, moveCursor, numberColumnsOf, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, useChrome, windowCount, withHeaders, withoutItem, workCount, writeCache };
5365
+ export { ActionMenu, App, COLS, CiStatusLine, CommentsPanel, DEFAULT_FOCUS_EMPTY, DEFAULT_FOCUS_LABEL, FOCUS_JUMP_KEY, FOCUS_MARK, FocusSlotLine, HealthPanel, LookupMiss, MIN_SIDEBAR_COLS, PrRow, SIDEBAR_COLS, SidePanel, StatusStripLine, ageLabel, budgetNotice, buildActions, buildCheckoutCmd, clipboard, counts, drillCmd, explainGhAction, explainItem, fitCount, focusCellFor, focusRefColor, gapsAbove, healthColor, healthDisplay, healthGlyph, healthLegend, isMenuGap, itermRun, jumpToRepo, jumpToRepoPane, matchesFilter, maxViewStart, menuRowsOf, menuTone, moveCursor, numberColumnsOf, openInTab, parsePatterns, railCapacity, railHeights, railRowsOf, railWidth, railsOf, readCache, renderMarkdown, reposInSections, resolveRepoPath, runHere, runInPane, runInPaneHorizontal, sameCiStatusState, sectionShedOf, signatureOf, stripGlyph, stripLayout, stripSignature, toCiStatusState, trailingColumnsOf, truncate, useActionMenu, useChrome, windowCount, withHeaders, withoutItem, workCount, writeCache };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kud/gh-ink",
3
- "version": "0.75.0",
3
+ "version": "0.75.1",
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",