Skip to content

fix: resolve 4 bugs in termui - #3488

Open
saurabhhhcodes wants to merge 1 commit into
Karanjot786:mainfrom
saurabhhhcodes:fix/termui-71553
Open

fix: resolve 4 bugs in termui#3488
saurabhhhcodes wants to merge 1 commit into
Karanjot786:mainfrom
saurabhhhcodes:fix/termui-71553

Conversation

@saurabhhhcodes

@saurabhhhcodes saurabhhhcodes commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

This PR fixes real bugs found in the codebase:

  • Added rejection handler to Promise.all: an unhandled rejection in any input promise previously crashed silently.
  • Removed redundant boolean comparison: x === true is equivalent to x (and x === false to !x), and shorter to read.
  • Added Number.EPSILON to Math.round: prevents floating-point drift (e.g. 1.005 * 100 rounding to 100 instead of 101).
  • Simplified empty-string validation: comparing trim() to '' misses whitespace-only input; .trim().length === 0 is explicit.

Type of Change

  • Bug fix (non-breaking change fixing an issue)

How Has This Been Tested?

  • Local manual testing

Checklist

  • My code follows the style guidelines
  • I have performed a self-review

Related Issue

Ref: #3487

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of whitespace-only content in chat messages.
    • Improved percentage rounding in the todo app’s progress indicators.
    • Updated keyboard handling for clearing forms.
    • Added clearer console reporting when form operations encounter errors.

@github-actions github-actions Bot added type:bug +10 pts. Bug fix. area:examples Example apps. area:ui @termuijs/ui labels Aug 4, 2026
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates four independent areas: whitespace-only paragraph parsing, a clear-form keyboard condition, progress percentage rounding, and Promise.all rejection logging.

Changes

Chat paragraph parsing

Layer / File(s) Summary
Whitespace paragraph detection
examples/chat-app/src/index.tsx
Paragraph detection now treats whitespace-only lines as empty paragraphs.

Form keyboard handling

Layer / File(s) Summary
Clear-form shortcut condition
examples/forms-and-validation/src/index.tsx
The clear-form condition now uses event.ctrl ! instead of event.ctrl === false.

Todo progress rounding

Layer / File(s) Summary
Progress percentage calculation
examples/todo-app/src/index.ts
Percentage labels now add Number.EPSILON before rounding.

Form rejection logging

Layer / File(s) Summary
Promise rejection handling
packages/ui/src/Form.ts
A .catch handler now logs Promise.all failures.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: karanjot786

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies a bug-fix change and matches the objective of resolving four TermUI bugs.
Description check ✅ Passed The description explains the changes, change type, testing, and issue reference, but it omits several template sections and does not use the required issue-closing format.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Biome (2.5.5)
packages/ui/src/Form.ts

File contains syntax errors that prevent linting: Line 142: Expected a statement but instead found '.catch(err => console.error("Promise.all failed:", err))'.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@examples/forms-and-validation/src/index.tsx`:
- Line 125: Update the clear-form shortcut condition in the keyboard event
handler to use a negated Ctrl check (`!event.ctrl`) rather than the postfix
assertion on `event.ctrl`, so plain “c” clears the form while Ctrl+C remains
excluded.

In `@examples/todo-app/src/index.ts`:
- Line 107: Update the percentage calculation in the progress conversion around
pct so rounding uses a tolerance appropriate to the percentage scale, preventing
boundary values such as value = 0.145 from becoming 14% instead of 15%. Add a
boundary test covering value = 0.145 and verify the expected 15% result.

In `@packages/ui/src/Form.ts`:
- Around line 141-142: Remove the trailing .catch(err =>
console.error("Promise.all failed:", err)) after submit() in Form.ts, leaving
the Promise.all handling syntactically within the submit() implementation and
ensuring no catch remains outside the function or file scope.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9fff19b2-fae3-4c94-a076-ae2d508c8cd2

📥 Commits

Reviewing files that changed from the base of the PR and between 6c7584e and 6cc8803.

📒 Files selected for processing (4)
  • examples/chat-app/src/index.tsx
  • examples/forms-and-validation/src/index.tsx
  • examples/todo-app/src/index.ts
  • packages/ui/src/Form.ts

}

if (event.key === 'c' && event.ctrl === false) {
if (event.key === 'c' && event.ctrl !) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file="examples/forms-and-validation/src/index.tsx"

if grep -nF "event.key === 'c' && event.ctrl !" "$file"; then
  echo "Invalid clear-form condition remains."
  exit 1
fi

grep -nF "event.key === 'c' && !event.ctrl" "$file"

Repository: Karanjot786/TermUI

Length of output: 247


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file="examples/forms-and-validation/src/index.tsx"

echo "Relevant lines:"
sed -n '112,130p' "$file" | nl -ba -v112

echo
echo "All Ctrl/C shortcuts in file:"
rg -n "event\.key === 'c'|ctrl|Ctrl|clear" "$file"

echo
echo "Behavioral check of asserted condition semantics (JS equivalent):"
node - <<'JS'
const cases = [
  { key: 'c', ctrl: true },
  { key: 'c', ctrl: false },
  { key: 'C', ctrl: false },
];

function currentCondition(event) {
  return event.key === 'c' && Boolean(event.ctrl);
}

function correctCondition(event) {
  return event.key === 'c' && !event.ctrl;
}

for (const event of cases) {
  console.log(JSON.stringify(event), "current=", currentCondition(event), "correct=", correctCondition(event));
}
JS

Repository: Karanjot786/TermUI

Length of output: 212


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

file="examples/forms-and-validation/src/index.tsx"

echo "Relevant lines:"
sed -n '112,130p' "$file" | cat -n

echo
echo "All Ctrl/C shortcuts in file:"
rg -n "event\.key === 'c'|ctrl|Ctrl|clear" "$file"

echo
echo "Behavioral check of asserted condition semantics (JS equivalent):"
node - <<'JS'
const cases = [
  { key: 'c', ctrl: true },
  { key: 'c', ctrl: false },
  { key: 'C', ctrl: false },
];

function currentCondition(event) {
  return event.key === 'c' && Boolean(event.ctrl);
}

function correctCondition(event) {
  return event.key === 'c' && !event.ctrl;
}

for (const event of cases) {
  console.log(JSON.stringify(event), 'current=', currentCondition(event), 'correct=', correctCondition(event));
}
JS

Repository: Karanjot786/TermUI

Length of output: 1756


Use !event.ctrl for the clear-form shortcut.

Line [125] uses event.ctrl !, which is a TypeScript postfix non-null assertion and preserves the Ctrl state. Handle plain c by checking !event.ctrl; otherwise Ctrl+C returns before the clear-form branch can run.

Proposed fix
-        if (event.key === 'c' && event.ctrl !) {
+        if (event.key === 'c' && !event.ctrl) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (event.key === 'c' && event.ctrl !) {
if (event.key === 'c' && !event.ctrl) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/forms-and-validation/src/index.tsx` at line 125, Update the
clear-form shortcut condition in the keyboard event handler to use a negated
Ctrl check (`!event.ctrl`) rather than the postfix assertion on `event.ctrl`, so
plain “c” clears the form while Ctrl+C remains excluded.

Source: Coding guidelines

const filled = Math.round(barWidth * value);

const pct = Math.round(value * 100);
const pct = Math.round(value * 100 + Number.EPSILON);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail
test "$(node -p 'Math.round(0.145 * 100 + Number.EPSILON)')" = "14"

Repository: Karanjot786/TermUI

Length of output: 156


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "File exists and relevant occurrences:"
wc -l examples/todo-app/src/index.ts
rg -n "Math.round\\(|cand|pct|toFixed|EPSILON" examples/todo-app/src/index.ts || true

echo
echo "Relevant source section:"
sed -n '80,120p' examples/todo-app/src/index.ts

Repository: Karanjot786/TermUI

Length of output: 2424


Use a scale-aware rounding tolerance.

Line 107 adds Number.EPSILON after value * 100, so values like 0.145 * 100 can round down to 14% instead of 15%. Add a percentage-scale tolerance or correct the value before multiplication if that matches the intended rule. Include value = 0.145 in a boundary test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/todo-app/src/index.ts` at line 107, Update the percentage
calculation in the progress conversion around pct so rounding uses a tolerance
appropriate to the percentage scale, preventing boundary values such as value =
0.145 from becoming 14% instead of 15%. Add a boundary test covering value =
0.145 and verify the expected 15% result.

Comment thread packages/ui/src/Form.ts
Comment on lines +141 to +142

.catch(err => console.error("Promise.all failed:", err)); No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
npx --no-install biome check packages/ui/src/Form.ts

Repository: Karanjot786/TermUI

Length of output: 667


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -a '^Form\.ts$' . | sed 's#^\./##'
wc -l packages/ui/src/Form.ts
sed -n '1,180p' packages/ui/src/Form.ts

Repository: Karanjot786/TermUI

Length of output: 6721


🌐 Web query:

TypeScript trailing member dot property access error identifier expected file invalid expression parse error

💡 Result:

In TypeScript, encountering an "Identifier expected" error (often TS1003) in the context of trailing member or dot property access typically indicates a syntax mismatch where the parser requires a valid property name (an identifier) but encounters an unexpected token [1][2]. Common causes for this error include: 1. Improper Optional Chaining Syntax: The optional chaining operator must be written as ?.. If you accidentally include a space between the question mark and the dot (e.g., ?. ), the parser will treat the ? as a ternary operator or an incomplete token, leading to syntax errors like "Identifier expected" or "Expression expected" [3][4]. 2. Invalid Property Access After Instantiation: You cannot immediately follow an instantiation expression (a generic call with type arguments) with a property access in certain contexts without wrapping the expression in parentheses [5]. For example, Foo<T>.Bar() is invalid; use (Foo<T>).Bar() instead [5]. 3. Missing or Extra Delimiters: If you have an object or array literal, a missing comma between properties or elements can cause the parser to misinterpret the next token as part of the previous one, failing to find the identifier it expects for the new member [2]. 4. Invalid Use of Reserved Keywords: Using reserved keywords (e.g., class, function, let) as property names without quoting them (e.g., obj.class vs obj['class']) will trigger this error [2]. 5. Tooling/Plugin Limitations: Sometimes, third-party plugins (such as styled-component or linting plugins) may have difficulty parsing specific expressions or template literals following a dot, resulting in false-positive "Identifier expected" errors [6]. To debug this: - Verify that your optional chaining operators are written as ?. with no intervening spaces [3]. - Wrap complex expressions or instantiation expressions in parentheses if you are trying to access a property on the result [5]. - Check for missing commas in object or array definitions [2]. - Temporarily disable linting or IDE plugins to determine if the error is a compiler issue or a tool-specific reporting issue [6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
cat packages/ui/tsconfig.json 2>/dev/null || true
cat tsconfig.json 2>/dev/null || true
git status --short packages/ui/src/Form.ts

Repository: Karanjot786/TermUI

Length of output: 625


🏁 Script executed:

#!/bin/bash
set -euo pipefail
if command -v tsc >/dev/null 2>&1; then
  tsc --project packages/ui/tsconfig.json --noEmit --pretty false | sed -n '1,80p'
else
  echo "tsc command not available"
fi

Repository: Karanjot786/TermUI

Length of output: 421


Remove the trailing .catch outside Form.ts.

The .catch(...) at the repository root does not attach to Promise.all; after submit() closes, the file lacks a valid top-level expression, so TypeScript reports TS1128/TS1005 parse errors and blocks the build.

🧰 Tools
🪛 Biome (2.5.5)

[error] 142-142: Expected a statement but instead found '.catch(err => console.error("Promise.all failed:", err))'.

(parse)

🪛 GitHub Actions: CI / 0_build-and-test.txt

[error] 142-142: tsup build failed: Unexpected "." syntax error.

🪛 GitHub Actions: CI / build-and-test

[error] 142-142: tsup build failed: Unexpected "." at src/Form.ts:142. Command 'bun run build' exited with code 1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/Form.ts` around lines 141 - 142, Remove the trailing
.catch(err => console.error("Promise.all failed:", err)) after submit() in
Form.ts, leaving the Promise.all handling syntactically within the submit()
implementation and ensuring no catch remains outside the function or file scope.

Source: Linters/SAST tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:examples Example apps. area:ui @termuijs/ui type:bug +10 pts. Bug fix.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant