@lewishowles/cli-style 0.12.0 → 0.12.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/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.12.1 - 2026-08-20
6
+
7
+ ### Fixed
8
+
9
+ - Fixed `row()` (and `rowGroup()`) wrapping long values one character per line when a long label left very little room for the value. Values now print unwrapped when the available width is too small to wrap usefully; an explicit `wrapWidth` still overrides the fallback.
10
+
5
11
  ## 0.12.0 - 2026-08-20
6
12
 
7
13
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lewishowles/cli-style",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Shared terminal output styles for Lewis Howles tools, diagnostics, and package CLIs.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -831,6 +831,10 @@ function renderPrimitives(options) {
831
831
  wrap: false,
832
832
  },
833
833
  ),
834
+ row("Long label ".repeat(10), "pending (chk_example)", {
835
+ ...options,
836
+ width: 80,
837
+ }),
834
838
  "",
835
839
  "Row groups",
836
840
  rowGroup({
@@ -11,6 +11,9 @@ const defaultSeparator = " ";
11
11
  // Keeps a wrapped value within a typical narrow terminal column.
12
12
  const defaultWrapWidth = 64;
13
13
 
14
+ // Avoid character-per-line wrapping when labels leave no useful value width.
15
+ const minimumWrapWidth = 10;
16
+
14
17
  /**
15
18
  * Render a labelled value row.
16
19
  *
@@ -33,7 +36,9 @@ const defaultWrapWidth = 64;
33
36
  * @param {string} options.valueColour
34
37
  * Optional colour token for the value.
35
38
  * @param {number} options.width
36
- * Total row width used to calculate the available value width.
39
+ * Total row width used to calculate the available value width. When a
40
+ * long label leaves less than the minimum wrap width, the value renders
41
+ * unwrapped on one line instead of wrapping.
37
42
  * @param {boolean} options.wrap
38
43
  * Set to false to keep the value on one line instead of wrapping it.
39
44
  * @param {number} options.wrapWidth
@@ -54,16 +59,23 @@ export function row(label, value = "", options = {}) {
54
59
 
55
60
  const renderedValue = renderValue(value, options);
56
61
  const separator = options.separator ?? defaultSeparator;
62
+ const unwrappedRow = `${renderedLabel}${separator}${renderedValue}`;
57
63
 
58
64
  if (options.wrap === false) {
59
- return `${renderedLabel}${separator}${renderedValue}`;
65
+ return unwrappedRow;
66
+ }
67
+
68
+ const availableWrapWidth = Number.isFinite(options.width)
69
+ ? options.width - labelWidth - separator.length
70
+ : defaultWrapWidth;
71
+
72
+ const hasExplicitWrapWidth = options.wrapWidth !== undefined && options.wrapWidth !== null;
73
+
74
+ if (!hasExplicitWrapWidth && availableWrapWidth < minimumWrapWidth) {
75
+ return unwrappedRow;
60
76
  }
61
77
 
62
- const wrapWidth =
63
- options.wrapWidth ??
64
- (Number.isFinite(options.width)
65
- ? Math.max(1, options.width - labelWidth - separator.length)
66
- : defaultWrapWidth);
78
+ const wrapWidth = options.wrapWidth ?? availableWrapWidth;
67
79
 
68
80
  const valueLines = wrapText(value, wrapWidth);
69
81
  const continuationIndent = " ".repeat(labelWidth + separator.length);