Skip to content

Fix string-width miscalculation for single-cell UI symbols#784

Closed
okets wants to merge 1 commit into
vadimdemedes:masterfrom
okets:master
Closed

Fix string-width miscalculation for single-cell UI symbols#784
okets wants to merge 1 commit into
vadimdemedes:masterfrom
okets:master

Conversation

@okets
Copy link
Copy Markdown

@okets okets commented Oct 6, 2025

Summary

Fixes an issue where common UI symbols (▶, ◀, ⚠, ℹ) were being incorrectly measured as width 2 by string-width, causing layout breaks in fixed-width containers.

Problem

The string-width library uses the East Asian Width property, which marks certain common UI symbols as "Ambiguous". This causes them to be treated as wide characters (width 2) even though they display as single-width (width 1) in modern terminals.

When these characters are used in Ink components, they cause:

  • Incorrect text alignment
  • Layout overflow in fixed-width containers
  • Visual artifacts from spacing calculations

Solution

Introduced a SINGLE_WIDTH_OVERRIDES set that explicitly maps characters incorrectly measured by string-width to their correct width (1). The width calculation now checks this override map before falling back to string-width.

Changes

  • Added SINGLE_WIDTH_OVERRIDES constant with verified single-width characters
  • Modified character width calculation in src/output.ts:227 to check overrides first
  • Added comprehensive documentation explaining the issue and verification criteria

Test Plan

  • ✅ Verified each character displays as single-width in modern terminals
  • ✅ Confirmed string-width incorrectly measures these as width 2
  • ✅ Tested that the fix prevents layout breaks in fixed-width containers

@okets
Copy link
Copy Markdown
Author

okets commented Oct 6, 2025

I just went over to fix the problem at the source (string-width library)
I figured out that in string-width version 7.2.0 (ink uses this), the bug exists
But in string-width version 8.1.0 (latest) , the bug is fixed.

solving this bug could be as easy as updating string-width to version 8.1.0.

@wu-json
Copy link
Copy Markdown
Contributor

wu-json commented Oct 15, 2025

I just went over to fix the problem at the source (string-width library) I figured out that in string-width version 7.2.0 (ink uses this), the bug exists But in string-width version 8.1.0 (latest) , the bug is fixed.

solving this bug could be as easy as updating string-width to version 8.1.0.

Also experiencing this right now. @okets Is that upgrade something you want to take on? If not I can also help out.

The issue where single-cell UI symbols (▶, ◀, ⚠, ℹ) were miscalculated
as two-cell characters originated in the string-width library. Updating
from 7.2.0 to 8.1.0 resolves this bug at the source.

This eliminates the need for the workaround patch previously implemented.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@okets
Copy link
Copy Markdown
Author

okets commented Oct 15, 2025

@wu-json I just pushed my changes. waiting for someone to appove the PR.

@LilaRest
Copy link
Copy Markdown

I tried patching Ink locally to use "string-width": "^8.1.0", but it didn't seem to fix the issue for me.
I still observe layout shifts with those symbol: and .

@sindresorhus
Copy link
Copy Markdown
Collaborator

"string-width": "^8.1.0",

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants