Skip to content

Commit

Permalink
fix: correctly handle arbitrary unicode character widths
Browse files Browse the repository at this point in the history
This improves support for emojis and non-latin languages.

Closes maticzav#249
  • Loading branch information
Kenneth-Sills committed Aug 6, 2024
1 parent a281c17 commit 45be034
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"component"
],
"dependencies": {
"object-hash": "^2.0.3"
"object-hash": "^2.0.3",
"string-width": "^7.2.0"
},
"devDependencies": {
"@types/jest": "26.0.24",
Expand Down
3 changes: 2 additions & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { Box, Text } from 'ink'
import { sha1 } from 'object-hash'
import stringWidth from 'string-width'

/* Table */

Expand Down Expand Up @@ -92,7 +93,7 @@ export default class Table<T extends ScalarDict> extends React.Component<
const value = data[key]

if (value == undefined || value == null) return 0
return String(value).length
return stringWidth(String(value))
})

const width = Math.max(...data, header) + padding * 2
Expand Down
79 changes: 79 additions & 0 deletions tests/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -485,4 +485,83 @@ test('Renders table with custom skeleton.', () => {
expect(actual()).toBe(expected())
})

test('Renders table with wide characters.', () => {
const data = [
{ name: '全角', width: 4 },
{ name: 'ハンカク', width: 4 },
{ name: '😀', width: 2 },
]
const { lastFrame: actual } = render(<Table data={data} skeleton={Custom} />)

const { lastFrame: expected } = render(
<>
<Box>
{custom('┌')}
{custom('──────')}
{custom('┬')}
{custom('─────')}
{custom('┐')}
</Box>
<Box>
{custom('│')}
{header(' name ')}
{custom('│')}
{header(' width ')}
{custom('│')}
</Box>
<Box>
{custom('├')}
{custom('──────')}
{custom('┼')}
{custom('─────')}
{custom('┤')}
</Box>
<Box>
{custom('│')}
{cell(' 全角 ')}
{custom('│')}
{cell(' 4 ')}
{custom('│')}
</Box>
<Box>
{custom('├')}
{custom('──────')}
{custom('┼')}
{custom('─────')}
{custom('┤')}
</Box>
<Box>
{custom('│')}
{cell(' ハンカク ')}
{custom('│')}
{cell(' 4 ')}
{custom('│')}
</Box>
<Box>
{custom('├')}
{custom('──────')}
{custom('┼')}
{custom('─────')}
{custom('┤')}
</Box>
<Box>
{custom('│')}
{cell(' 😀 ')}
{custom('│')}
{cell(' 2 ')}
{custom('│')}
</Box>
<Box>
{custom('└')}
{custom('──────')}
{custom('┴')}
{custom('─────')}
{custom('┘')}
</Box>
</>,
)

expect(actual()).toBe(expected())
})

// ---------------------------------------------------------------------------
31 changes: 31 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,11 @@ ansi-regex@^5.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==

ansi-regex@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==

ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
Expand Down Expand Up @@ -1322,6 +1327,11 @@ emittery@^0.7.1:
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.7.2.tgz#25595908e13af0f5674ab419396e2fb394cdfa82"
integrity sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==

emoji-regex@^10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23"
integrity sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==

emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
Expand Down Expand Up @@ -1605,6 +1615,11 @@ get-caller-file@^2.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==

get-east-asian-width@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e"
integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==

get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
Expand Down Expand Up @@ -3667,13 +3682,29 @@ string-width@^4.2.2:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"

string-width@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.2.0.tgz#b5bb8e2165ce275d4d43476dd2700ad9091db6dc"
integrity sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==
dependencies:
emoji-regex "^10.3.0"
get-east-asian-width "^1.0.0"
strip-ansi "^7.1.0"

strip-ansi@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
dependencies:
ansi-regex "^5.0.0"

strip-ansi@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
dependencies:
ansi-regex "^6.0.1"

strip-bom@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878"
Expand Down

0 comments on commit 45be034

Please sign in to comment.