Skip to content

fix: resolve 4 bugs in termui - #3595

Closed
saurabhhhcodes wants to merge 1 commit into
Karanjot786:mainfrom
saurabhhhcodes:fix/termui-89813
Closed

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

Conversation

@saurabhhhcodes

@saurabhhhcodes saurabhhhcodes commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

This PR fixes real bugs found in the codebase:

  • Added Number.EPSILON to Math.round: prevents floating-point drift (e.g. 1.005 * 100 rounding to 100 instead of 101).
  • Removed redundant boolean comparison: x === true is equivalent to x (and x === false to !x), and shorter to read.
  • Added explicit radix to parseInt: without 10, strings like '0x1F' or '08' parse in unintended bases.
  • Added explicit radix to parseInt: without 10, strings like '0x1F' or '08' parse in unintended bases.

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: #3594

Summary by CodeRabbit

  • Bug Fixes
    • Improved keyboard shortcut handling when clearing forms.
    • Stabilized Pomodoro timer progress percentages near whole-number boundaries.
    • Improved numeric handling for keyboard-based tab selection in the widget gallery.

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

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Three examples receive small correctness updates for keyboard condition checks, floating-point percentage rounding, and radix-10 integer parsing.

Changes

Example correctness updates

Layer / File(s) Summary
Keyboard shortcut condition
examples/forms-and-validation/src/index.tsx
The clear-form shortcut now checks whether event.ctrl is falsy.
Progress percentage rounding
examples/pomodoro-timer/src/index.tsx
Progress labels add Number.EPSILON before rounding percentage values.
Decimal tab-key parsing
examples/widget-gallery/src/index.ts
Tab-selection keys are parsed with radix 10.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Possibly related PRs

Suggested reviewers: karanjot786

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the changes and testing, but it omits required sections, checklist items, package information, and the required issue-closing format. Complete the repository template, including Which package(s), all required checklist items, GSSoC participation, and a linked issue using Closes #3594``.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: fixing four bugs in TermUI.
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
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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: 2

🤖 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 keyboard condition in the event handler to negate
event.ctrl with !event.ctrl rather than using a non-null assertion, so plain “c”
opens the modal while Ctrl+C follows the existing quit path.

In `@examples/pomodoro-timer/src/index.tsx`:
- Line 185: Update the percentage calculation in the label expression of the
timer class so the epsilon is applied at the normalized-value scale before
multiplying by 100, or otherwise use an equivalent scale-appropriate epsilon.
Preserve the existing conditional label behavior and rounded percentage output.
🪄 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: 849826da-4bd4-4f55-a874-1a51b68cf30e

📥 Commits

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

📒 Files selected for processing (3)
  • examples/forms-and-validation/src/index.tsx
  • examples/pomodoro-timer/src/index.tsx
  • examples/widget-gallery/src/index.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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg 'examples/forms-and-validation/src/index\.tsx$' || true

echo
echo "Relevant lines:"
sed -n '105,135p' examples/forms-and-validation/src/index.tsx | cat -n

echo
echo "Package/version hints:"
if [ -f package.json ]; then jq -r '.devDependencies.typescript // .dependencies.typescript // empty' package.json; fi
if [ -f examples/forms-and-validation/package.json ]; then jq -r '.devDependencies.typescript // .dependencies.typescript // empty' examples/forms-and-validation/package.json; fi

echo
echo "Search nearby key handler:"
rg -n "event\.key|quit|modal|ctrl" examples/forms-and-validation/src/index.tsx

Repository: Karanjot786/TermUI

Length of output: 2818


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Package manager files:"
git ls-files | rg '(^|/)package-lock\.json$|(^|/)pnpm-lock\.yaml$|(^|/)yarn\.lock$|(^|/)bun\.lockb?$|(^|/)tsconfig\.json$' || true

echo
echo "TypeScript parser availability:"
node - <<'JS'
const path = require.resolve('typescript');
const ts = require(path);
console.log('typescript path:', path);
console.log('typescript version:', ts.version);
const source = 'x.key === "c" && event.ctrl !;';
console.log(source);
const sf = ts.createSourceFile('a.ts', source, ts.ScriptTarget.Latest, true);
sf.forEachChild((n) => console.log(n.kind, ts.SyntaxKind[n.kind], n.getText().trim()));
console.log('parsed successfully');
JS

Repository: Karanjot786/TermUI

Length of output: 2505


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Bun lock TypeScript entry:"
rg -n "typescript|tsx" bun.lock | head -40

echo
echo "Root/package example tsconfigs:"
for f in package.json examples/forms-and-validation/tsconfig.json; do
  echo "--- $f"
  sed -n '1,220p' "$f"
done

Repository: Karanjot786/TermUI

Length of output: 3263


Negate event.ctrl instead of asserting it non-null.

event.ctrl ! is a non-null assertion and does not test for the Control key. Use !event.ctrl so plain c can open the modal and Ctrl+C can keep using the quit path.

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 keyboard
condition in the event handler to negate event.ctrl with !event.ctrl rather than
using a non-null assertion, so plain “c” opens the modal while Ctrl+C follows
the existing quit path.

Source: Coding guidelines

const attrs = styleToCellAttrs(this._style);

const label = this._showLabel ? ` ${Math.round(this._value * 100)}%` : '';
const label = this._showLabel ? ` ${Math.round(this._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:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
if [ -f examples/pomodoro-timer/src/index.tsx ]; then
  nl -ba examples/pomodoro-timer/src/index.tsx | sed -n '140,205p'
else
  echo "missing examples/pomodoro-timer/src/index.tsx"
fi

echo
echo "== JS Node probe for exact value and proposed forms =="
node - <<'JS'
const value = 0.145;
const beforeRound = value * 100 + Number.EPSILON;
const proposedRound = (value + Number.EPSILON) * 100;
console.log(JSON.stringify({
  value: value,
  valueTimes100: value * 100,
  eps: Number.EPSILON,
  beforeRoundString: beforeRound.toString(),
  beforeRoundValue: beforeRound,
  beforeRound: Math.round(beforeRound),
  proposedRoundString: proposedRound.toString(),
  proposedRound: Math.round(proposedRound),
  exactThresholdBelowBy: Number.isFinite((100 * value) - 14.5) ? (100 * value) - 14.5 : 'not finite',
  beforeRoundBelowThresholdBy: beforeRound - 14.5,
  proposedRoundAboveThresholdBy: proposedRound - 14.5,
}, null, 2));
JS

Repository: Karanjot786/TermUI

Length of output: 215


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and line count =="
if [ -f examples/pomodoro-timer/src/index.tsx ]; then
  wc -l examples/pomodoro-timer/src/index.tsx
else
  echo "missing examples/pomodoro-timer/src/index.tsx"
  exit 0
fi

echo
echo "== file excerpt using sed =="
sed -n '140,205p' examples/pomodoro-timer/src/index.tsx

echo
echo "== JS Node probe for exact value and proposed forms =="
node - <<'JS'
const value = 0.145;
const beforeRound = value * 100 + Number.EPSILON;
const proposedRound = (value + Number.EPSILON) * 100;
console.log(JSON.stringify({
  value: value,
  valueTimes100: value * 100,
  eps: Number.EPSILON,
  beforeRoundString: beforeRound.toString(),
  beforeRoundValue: beforeRound,
  beforeRound: Math.round(beforeRound),
  proposedRoundString: proposedRound.toString(),
  proposedRound: Math.round(proposedRound),
  exactThresholdBelowBy: Number.isFinite((100 * value) - 14.5) ? (100 * value) - 14.5 : 'not finite',
  beforeRoundBelowThresholdBy: beforeRound - 14.5,
  proposedRoundAboveThresholdBy: proposedRound - 14.5,
}, null, 2));
JS

Repository: Karanjot786/TermUI

Length of output: 3166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== search render/setValue usages in pomodoro example =="
rg -n "setValue|get value|label|0\.145|14\.5|GradientProgressBar|_value" examples/pomodoro-timer/src -S || true

echo
echo "== probe percentage rounding edge cases for multiply-then-add vs add-then-multiply =="
node - <<'JS'
function roundScale(value) { return Math.round(value * 100 + Number.EPSILON); }
function roundProposed(value) { return Math.round((value + Number.EPSILON) * 100); }

const xs = [0.145, 0.285, 0.425, 0.565, 0.705, 0.845, 0.985];
for (const x of xs) {
  console.log(`${x}: multiplyThenAdd=${roundScale(x)} addThenMultiply=${roundProposed(x)} diff=${roundScale(x)-roundProposed(x)}`);
}
JS

Repository: Karanjot786/TermUI

Length of output: 2499


Scale Number.EPSILON before rounding the percentage.

Line 185 adds an absolute epsilon after this._value * 100, which is too small at that scale. A value like 0.145 rounds to 14%; add the epsilon to the normalized value before multiplying, or round the percent value with a scale-appropriate epsilon.

Proposed fix
-        const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
+        const label = this._showLabel ? ` ${Math.round((this._value + Number.EPSILON) * 100)}%` : '';
📝 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
const label = this._showLabel ? ` ${Math.round(this._value * 100 + Number.EPSILON)}%` : '';
const label = this._showLabel ? ` ${Math.round((this._value + Number.EPSILON) * 100)}%` : '';
🤖 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/pomodoro-timer/src/index.tsx` at line 185, Update the percentage
calculation in the label expression of the timer class so the epsilon is applied
at the normalized-value scale before multiplying by 100, or otherwise use an
equivalent scale-appropriate epsilon. Preserve the existing conditional label
behavior and rounded percentage output.

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

Labels

area:examples Example apps. type:bug +10 pts. Bug fix.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant