@sayknow-cli/tui 0.5.10 → 0.5.11

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,7 +2,11 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
- ## [0.5.10] - 2026-09-10
5
+ ## [0.5.11] - 2026-09-10
6
+
7
+ ### Added
8
+
9
+ - `SettingsList` accepts an optional `descriptionRows` constructor argument to reserve a fixed description-area height (default `0`, no change for existing callers).
6
10
 
7
11
  ## [0.5.7] - 2026-09-10
8
12
 
@@ -22,7 +22,7 @@ export interface SettingsListTheme {
22
22
  }
23
23
  export declare class SettingsList implements Component {
24
24
  #private;
25
- constructor(items: SettingItem[], maxVisible: number, theme: SettingsListTheme, onChange: (id: string, newValue: string) => void, onCancel: () => void, onSelectionChange?: (item: SettingItem | undefined) => void);
25
+ constructor(items: SettingItem[], maxVisible: number, theme: SettingsListTheme, onChange: (id: string, newValue: string) => void, onCancel: () => void, onSelectionChange?: (item: SettingItem | undefined) => void, descriptionRows?: number);
26
26
  /** Update an item's currentValue */
27
27
  updateValue(id: string, newValue: string): void;
28
28
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@sayknow-cli/tui",
4
- "version": "0.5.10",
4
+ "version": "0.5.11",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://sayknow-cli.com",
7
7
  "author": "jaybeyond",
@@ -38,8 +38,8 @@
38
38
  "fmt": "biome format --write ."
39
39
  },
40
40
  "dependencies": {
41
- "@sayknow-cli/natives": "0.5.10",
42
- "@sayknow-cli/utils": "0.5.10",
41
+ "@sayknow-cli/natives": "0.5.11",
42
+ "@sayknow-cli/utils": "0.5.11",
43
43
  "lru-cache": "11.3.6",
44
44
  "marked": "^18.0.3"
45
45
  },
@@ -33,6 +33,7 @@ export class SettingsList implements Component {
33
33
  #onChange: (id: string, newValue: string) => void;
34
34
  #onCancel: () => void;
35
35
  #onSelectionChange?: (item: SettingItem | undefined) => void;
36
+ #descriptionRows: number;
36
37
 
37
38
  // Submenu state
38
39
  #submenuComponent: Component | null = null;
@@ -45,6 +46,7 @@ export class SettingsList implements Component {
45
46
  onChange: (id: string, newValue: string) => void,
46
47
  onCancel: () => void,
47
48
  onSelectionChange?: (item: SettingItem | undefined) => void,
49
+ descriptionRows = 0,
48
50
  ) {
49
51
  this.#items = items;
50
52
  this.#maxVisible = maxVisible;
@@ -52,6 +54,7 @@ export class SettingsList implements Component {
52
54
  this.#onChange = onChange;
53
55
  this.#onCancel = onCancel;
54
56
  this.#onSelectionChange = onSelectionChange;
57
+ this.#descriptionRows = Math.max(0, descriptionRows);
55
58
  this.#notifySelectionChange();
56
59
  }
57
60
 
@@ -147,9 +150,18 @@ export class SettingsList implements Component {
147
150
  lines.push(this.#theme.hint(truncateToWidth(scrollText, width - 2, Ellipsis.Omit)));
148
151
  }
149
152
 
150
- // Add description for selected item
153
+ // Add description for selected item. Some hosts reserve a fixed
154
+ // description area so keyboard navigation does not resize the TUI when
155
+ // moving between described and undescribed rows.
151
156
  const selectedItem = this.#items[this.#selectedIndex];
152
- if (selectedItem?.description) {
157
+ if (this.#descriptionRows > 0) {
158
+ lines.push("");
159
+ const wrappedDesc = selectedItem?.description ? wrapTextWithAnsi(selectedItem.description, width - 4) : [];
160
+ for (let i = 0; i < this.#descriptionRows; i++) {
161
+ const line = wrappedDesc[i] ?? "";
162
+ lines.push(line ? this.#theme.description(` ${line}`) : "");
163
+ }
164
+ } else if (selectedItem?.description) {
153
165
  lines.push("");
154
166
  const wrappedDesc = wrapTextWithAnsi(selectedItem.description, width - 4);
155
167
  for (const line of wrappedDesc) {