Fix string-width miscalculation for single-cell UI symbols
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_OVERRIDESconstant with verified single-width characters - Modified character width calculation in
src/output.ts:227to 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-widthincorrectly measures these as width 2 - ✅ Tested that the fix prevents layout breaks in fixed-width containers
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.
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.
@wu-json I just pushed my changes. waiting for someone to appove the PR.
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 ✘.