fix: render tiny balances with unicode subscript#168
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds accessible amount formatting utilities and components (subscript-capable formatDisplayAmountParts, toSubscript, FormattedAmount, FormattedFeeList), replaces many string-formatting calls with these components across the React app, widens Dropdown label types to ReactNode, adjusts QuantityInput.ReadOnly props, and updates layout/scroll CSS and a few page wrappers. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Deploying interwovenkit-staging with
|
| Latest commit: |
a11ec46
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://834cc3cc.interwovenkit-staging.pages.dev |
| Branch Preview URL: | https://fix-tiny-balance-subscript-d.interwovenkit-staging.pages.dev |
Deploying interwovenkit-testnet with
|
| Latest commit: |
a11ec46
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://2f37cd5b.interwovenkit-testnet.pages.dev |
| Branch Preview URL: | https://fix-tiny-balance-subscript-d.interwovenkit-testnet.pages.dev |
Deploying interwovenkit with
|
| Latest commit: |
a11ec46
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5b9554fe.interwovenkit.pages.dev |
| Branch Preview URL: | https://fix-tiny-balance-subscript-d.interwovenkit.pages.dev |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
- Removed SubscriptParts and DisplayAmountParts interfaces - Removed getDisplayAmountParts function - Inlined logic directly into formatDisplayAmount - Simplifies code while maintaining same functionality Applied via @cursor push command
5d35e2b to
e966ad4
Compare
|
Bugbot Autofix prepared fixes for 2 of the 2 bugs found in the latest run.
Or push these changes by commenting: Preview (69a73104c0)diff --git a/packages/interwovenkit-react/src/components/FormattedAmount.tsx b/packages/interwovenkit-react/src/components/FormattedAmount.tsx
--- a/packages/interwovenkit-react/src/components/FormattedAmount.tsx
+++ b/packages/interwovenkit-react/src/components/FormattedAmount.tsx
@@ -1,4 +1,4 @@
-import { formatDisplayAmountParts } from "@/lib/format"
+import { formatDisplayAmountParts, toSubscript } from "@/lib/format"
import type { ComponentPropsWithoutRef } from "react"
@@ -18,7 +18,7 @@
return (
<span {...props}>
{parts.prefix}
- <sub>{parts.hiddenZeroCount}</sub>
+ {toSubscript(parts.hiddenZeroCount)}
{parts.significant}
</span>
)
diff --git a/packages/interwovenkit-react/src/lib/format.test.ts b/packages/interwovenkit-react/src/lib/format.test.ts
--- a/packages/interwovenkit-react/src/lib/format.test.ts
+++ b/packages/interwovenkit-react/src/lib/format.test.ts
@@ -1,7 +1,16 @@
import { describe, expect, it } from "vitest"
-import { formatDisplayAmount, formatValue } from "./format"
+import { formatDisplayAmountParts, formatValue, toSubscript } from "./format"
describe("formatDisplayAmount", () => {
+ function formatDisplayAmount(
+ amount: Parameters<typeof formatDisplayAmountParts>[0],
+ options: Parameters<typeof formatDisplayAmountParts>[1],
+ ) {
+ const parts = formatDisplayAmountParts(amount, options)
+ if (parts.kind === "plain") return parts.value
+ return `${parts.prefix}${toSubscript(parts.hiddenZeroCount)}${parts.significant}`
+ }
+
it("matches default amount formatting for regular amounts", () => {
expect(formatDisplayAmount("1234567", { decimals: 6 })).toBe("1.234567")
expect(formatDisplayAmount("1000000", { decimals: 6 })).toBe("1.000000")
diff --git a/packages/interwovenkit-react/src/lib/format.ts b/packages/interwovenkit-react/src/lib/format.ts
--- a/packages/interwovenkit-react/src/lib/format.ts
+++ b/packages/interwovenkit-react/src/lib/format.ts
@@ -9,7 +9,7 @@
dp?: number
}
-function toSubscript(value: number) {
+export function toSubscript(value: number) {
return String(value)
.split("")
.map((digit) => SUBSCRIPT_DIGITS[Number(digit)] ?? digit)
@@ -56,16 +56,6 @@
return { kind: "subscript", prefix, hiddenZeroCount, significant }
}
-export function formatDisplayAmount(
- amount: Parameters<typeof formatAmountBase>[0],
- options: FormatAmountOptions,
-) {
- const parts = formatDisplayAmountParts(amount, options)
- if (parts.kind === "plain") return parts.value
-
- return `${parts.prefix}${toSubscript(parts.hiddenZeroCount)}${parts.significant}`
-}
-
export function formatValue(value?: Parameters<typeof formatNumber>[0]) {
const absValue = value ? BigNumber(value).abs() : undefined
if (absValue && absValue.gt(0) && absValue.lt(0.01)) return "< $0.01" |
- Use Unicode subscript characters instead of HTML <sub> tags in FormattedAmount component - Export toSubscript function for production use - Remove unused formatDisplayAmount function and update tests to use formatDisplayAmountParts + toSubscript Applied via @cursor push command
…cript-display # Conflicts: # packages/interwovenkit-react/src/pages/deposit/TransferFields.tsx
Amp-Thread-ID: https://ampcode.com/threads/T-019d4e9e-58b3-7339-a01c-1ed95c24925d Co-authored-by: Amp <amp@ampcode.com>
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
packages/interwovenkit-react/src/public/app/Drawer.module.css (1)
75-85: Fix empty line formatting to pass Stylelint.Static analysis flagged empty lines before declarations at lines 78, 81, and 83. Remove these to conform to the project's CSS linting rules.
♻️ Proposed fix
.routes { flex: 1; - display: flex; flex-direction: column; - height: 100%; - min-height: 0; overflow: hidden; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/interwovenkit-react/src/public/app/Drawer.module.css` around lines 75 - 85, The .routes CSS rule contains stray blank lines before several declarations which violates Stylelint; open the .routes block in Drawer.module.css and remove the empty lines so each declaration (flex, display, flex-direction, height, min-height, overflow) immediately follows the previous line with no blank lines between them, preserving the same property order and values.packages/interwovenkit-react/src/lib/format.test.ts (1)
19-38: Add one negative tiny-amount regression.
packages/interwovenkit-react/src/lib/format.ts, Lines 55-56 has dedicated sign handling, but this suite never exercises the subscript path for negative values. One assertion here would lock that branch down.💡 Suggested test addition
it("shows subscript notation for tiny non-zero amounts hidden by 6dp", () => { expect(formatDisplayAmount("1", { decimals: 8 })).toBe("0.0₆1") expect(formatDisplayAmount("3159", { decimals: 10 })).toBe("0.0₅3159") + expect(formatDisplayAmount("-3159", { decimals: 10 })).toBe("-0.0₅3159") })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/interwovenkit-react/src/lib/format.test.ts` around lines 19 - 38, The test suite for formatDisplayAmount does not cover negative tiny amounts so the sign-handling branch in format.ts (the sign stripping/handling logic around formatDisplayAmount) is untested; add one assertion that passes a negative tiny amount string (e.g. formatDisplayAmount("-1", { decimals: 8 })) and expect the subscripted output to preserve the negative sign (e.g. "-0.0₆1"), thereby exercising the negative sign path and ensuring subscript logic and trailing-zero trimming behave the same for negatives.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/interwovenkit-react/src/components/FormattedAmount.tsx`:
- Around line 18-23: The rendered span in FormattedAmount currently replaces
numeric characters with decorative Unicode glyphs
(toSubscript(parts.hiddenZeroCount)), breaking screen-reader access; restore a
plain-text accessible numeric value by including the original numeric string
(e.g., concatenation of parts.prefix, hidden zeros, and parts.significant) as a
visible-to-assistive-tech element and keep the visual subscript run decorative —
mark the decorative glyph span produced by toSubscript(...) with
aria-hidden="true" (or role="presentation") and add a
screen-reader-only/plain-text span for the full numeric value so assistive tech
reads the real number while sighted users see the styled glyphs.
In `@packages/interwovenkit-react/src/components/FormattedFeeList.tsx`:
- Around line 9-13: Keep the zero fallback for missing fee amounts: in the JSX
returned by fees.map inside the FormattedFeeList component, ensure you pass a
default "0" for fee.amount (i.e., use fee.amount ?? "0") to the FormattedAmount
component so the shared fee list never renders an empty amount before the
symbol; update the JSX where FormattedAmount is used and keep the existing
decimals fallback (fee.origin_asset.decimals ?? 0).
In `@packages/interwovenkit-react/src/components/Scrollable.module.css`:
- Around line 2-9: Remove the extra blank lines inside the CSS declaration block
in Scrollable.module.css so there are no empty lines between declarations (flex,
min-height, overflow, -webkit-overflow-scrolling, overflow-y,
overscroll-behavior). Edit the block that contains those properties so each
declaration appears on its own line with no blank lines between them, which will
satisfy stylelint's declaration-empty-line-before rule; preserve the existing
property order and values.
In `@packages/interwovenkit-react/src/pages/autosign/EnableAutoSign.module.css`:
- Around line 1-11: The .page CSS block contains extra blank lines between
declarations that trigger stylelint's declaration-empty-line-before rule; edit
the .page rule (class selector ".page") to remove the unnecessary empty lines so
declarations are adjacent (or otherwise conform to your project's
declaration-empty-line-before configuration), ensuring no blank lines precede
property declarations inside the .page block.
In `@packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx`:
- Around line 115-117: getDp currently forces an 8-decimal display for amounts
that formatAmountBase(...) === "0.000000", which prevents the fee footer from
using the new tiny-amount compact/subscript rendering; change getDp so it does
not return 8 in that case (leave dp undefined) — i.e., remove the conditional
that returns 8 (or always return undefined) so the fee footer will opt into the
tiny-balance rendering path that formatAmountBase supports.
In `@packages/interwovenkit-react/src/pages/tx/TxRequest.module.css`:
- Around line 1-11: The .page CSS rule in TxRequest.module.css has extra blank
lines between declarations triggering stylelint's declaration-empty-line-before;
remove the blank lines so declarations are consecutively listed (e.g., collapse
the spacing between "flex: 1;", "display: flex;", "flex-direction: column;",
"height: 100%;", "min-height: 0;", and "overflow: hidden;") to satisfy the
linter while keeping the same properties and order.
In `@packages/interwovenkit-react/src/public/app/Drawer.tsx`:
- Around line 109-111: The .routes container in Drawer.tsx (where AsyncBoundary
renders {children}) likely applies overflow constraints that will clip many
routed pages; update the routed components (BridgeForm, BridgeHistory,
BridgePreview, Connect, Deposit, ManageAutoSign, NftDetails, Receive, Send,
SendNft, Settings, TransferCompleted, Withdraw, Withdrawals) so their top-level
render is wrapped in a Scrollable component or a div with
className={styles.page}, or alternatively change the styles.routes rules to not
constrain overflow/height so children can manage scrolling; locate the top-level
return in each component (or the AsyncBoundary render in Drawer.tsx) and apply
one of those two fixes consistently.
---
Nitpick comments:
In `@packages/interwovenkit-react/src/lib/format.test.ts`:
- Around line 19-38: The test suite for formatDisplayAmount does not cover
negative tiny amounts so the sign-handling branch in format.ts (the sign
stripping/handling logic around formatDisplayAmount) is untested; add one
assertion that passes a negative tiny amount string (e.g.
formatDisplayAmount("-1", { decimals: 8 })) and expect the subscripted output to
preserve the negative sign (e.g. "-0.0₆1"), thereby exercising the negative sign
path and ensuring subscript logic and trailing-zero trimming behave the same for
negatives.
In `@packages/interwovenkit-react/src/public/app/Drawer.module.css`:
- Around line 75-85: The .routes CSS rule contains stray blank lines before
several declarations which violates Stylelint; open the .routes block in
Drawer.module.css and remove the empty lines so each declaration (flex, display,
flex-direction, height, min-height, overflow) immediately follows the previous
line with no blank lines between them, preserving the same property order and
values.
🪄 Autofix (Beta)
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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 357dd31b-dbe3-403a-8418-ab18d0561cad
📒 Files selected for processing (32)
packages/interwovenkit-react/src/components/Dropdown.tsxpackages/interwovenkit-react/src/components/FormattedAmount.tsxpackages/interwovenkit-react/src/components/FormattedFeeList.tsxpackages/interwovenkit-react/src/components/Scrollable.module.csspackages/interwovenkit-react/src/components/form/AssetOptions.tsxpackages/interwovenkit-react/src/components/form/QuantityInput.tsxpackages/interwovenkit-react/src/lib/format.test.tspackages/interwovenkit-react/src/lib/format.tspackages/interwovenkit-react/src/pages/autosign/EnableAutoSign.module.csspackages/interwovenkit-react/src/pages/autosign/EnableAutoSign.tsxpackages/interwovenkit-react/src/pages/bridge/BridgeFields.tsxpackages/interwovenkit-react/src/pages/bridge/BridgeHistoryItem.tsxpackages/interwovenkit-react/src/pages/bridge/OperationItem.tsxpackages/interwovenkit-react/src/pages/bridge/SelectRouteOption.tsxpackages/interwovenkit-react/src/pages/bridge/data/format.test.tspackages/interwovenkit-react/src/pages/bridge/data/format.tspackages/interwovenkit-react/src/pages/bridge/op/ClaimableList.tsxpackages/interwovenkit-react/src/pages/bridge/op/WithdrawalAsset.tsxpackages/interwovenkit-react/src/pages/deposit/SelectExternalAsset.tsxpackages/interwovenkit-react/src/pages/deposit/TransferFields.tsxpackages/interwovenkit-react/src/pages/deposit/TransferFooter.tsxpackages/interwovenkit-react/src/pages/deposit/TransferTxDetails.tsxpackages/interwovenkit-react/src/pages/tx/TxFee.tsxpackages/interwovenkit-react/src/pages/tx/TxFeeInsufficient.tsxpackages/interwovenkit-react/src/pages/tx/TxRequest.module.csspackages/interwovenkit-react/src/pages/tx/TxRequest.tsxpackages/interwovenkit-react/src/pages/tx/TxSimulate.tsxpackages/interwovenkit-react/src/pages/wallet/tabs/activity/ActivityChanges.tsxpackages/interwovenkit-react/src/pages/wallet/tabs/portfolio/AssetBalance.tsxpackages/interwovenkit-react/src/pages/wallet/txs/send/SendFields.tsxpackages/interwovenkit-react/src/public/app/Drawer.module.csspackages/interwovenkit-react/src/public/app/Drawer.tsx
💤 Files with no reviewable changes (1)
- packages/interwovenkit-react/src/pages/bridge/data/format.ts
Amp-Thread-ID: https://ampcode.com/threads/T-019d4e9e-58b3-7339-a01c-1ed95c24925d Co-authored-by: Amp <amp@ampcode.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/interwovenkit-react/src/components/Dropdown.tsx`:
- Around line 11-12: The Dropdown component uses the prop triggerLabel (typed as
ReactNode) and currently falls back using the logical OR operator; update the
fallback to use the nullish coalescing operator so valid falsy ReactNodes (like
0 or "") are not treated as absent—replace the usage of "triggerLabel || <...>"
with "triggerLabel ?? <...>" where the Dropdown renders or computes the trigger
label (search for triggerLabel in the Dropdown component to locate the
expression).
🪄 Autofix (Beta)
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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 4ddeedef-046e-4231-bddc-51f1bb2e18f0
📒 Files selected for processing (16)
packages/interwovenkit-react/src/components/Dropdown.tsxpackages/interwovenkit-react/src/components/form/QuantityInput.tsxpackages/interwovenkit-react/src/lib/format.test.tspackages/interwovenkit-react/src/lib/format.tspackages/interwovenkit-react/src/pages/autosign/EnableAutoSign.tsxpackages/interwovenkit-react/src/pages/bridge/BridgeFields.tsxpackages/interwovenkit-react/src/pages/bridge/BridgeHistoryItem.tsxpackages/interwovenkit-react/src/pages/bridge/SelectRouteOption.tsxpackages/interwovenkit-react/src/pages/bridge/data/format.tspackages/interwovenkit-react/src/pages/deposit/SelectExternalAsset.tsxpackages/interwovenkit-react/src/pages/deposit/TransferFields.tsxpackages/interwovenkit-react/src/pages/deposit/TransferFooter.tsxpackages/interwovenkit-react/src/pages/deposit/TransferTxDetails.tsxpackages/interwovenkit-react/src/pages/tx/TxRequest.tsxpackages/interwovenkit-react/src/pages/wallet/txs/send/SendFields.tsxpackages/interwovenkit-react/src/public/app/Drawer.tsx
💤 Files with no reviewable changes (1)
- packages/interwovenkit-react/src/pages/bridge/data/format.ts
✅ Files skipped from review due to trivial changes (6)
- packages/interwovenkit-react/src/public/app/Drawer.tsx
- packages/interwovenkit-react/src/pages/tx/TxRequest.tsx
- packages/interwovenkit-react/src/pages/deposit/SelectExternalAsset.tsx
- packages/interwovenkit-react/src/pages/wallet/txs/send/SendFields.tsx
- packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
- packages/interwovenkit-react/src/pages/autosign/EnableAutoSign.tsx
🚧 Files skipped from review as they are similar to previous changes (6)
- packages/interwovenkit-react/src/pages/bridge/SelectRouteOption.tsx
- packages/interwovenkit-react/src/pages/bridge/BridgeHistoryItem.tsx
- packages/interwovenkit-react/src/pages/bridge/BridgeFields.tsx
- packages/interwovenkit-react/src/lib/format.test.ts
- packages/interwovenkit-react/src/pages/deposit/TransferTxDetails.tsx
- packages/interwovenkit-react/src/lib/format.ts
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Dead
formatFeesfunction and tests not removed- Removed the unused
formatFeesexport and its obsolete tests, along with now-unused imports.
- Removed the unused
Or push these changes by commenting:
@cursor push 1d13597572
Preview (1d13597572)
diff --git a/packages/interwovenkit-react/src/pages/bridge/data/format.test.ts b/packages/interwovenkit-react/src/pages/bridge/data/format.test.ts
--- a/packages/interwovenkit-react/src/pages/bridge/data/format.test.ts
+++ b/packages/interwovenkit-react/src/pages/bridge/data/format.test.ts
@@ -1,4 +1,4 @@
-import { calculateMinimumReceived, formatDuration, formatFees } from "./format"
+import { calculateMinimumReceived, formatDuration } from "./format"
describe("calculateMinimumReceived", () => {
it("applies slippage to amount", () => {
@@ -61,26 +61,3 @@
expect(formatDuration(3600)).toBe("1h")
})
})
-
-describe("formatFees", () => {
- it("formats a single fee entry", () => {
- const fees = [{ amount: "1234567", origin_asset: { decimals: 6, symbol: "INIT" } }]
- // @ts-expect-error unused values are not defined
- expect(formatFees(fees)).toBe("1.234567 INIT")
- })
-
- it("formats multiple fee entries", () => {
- const fees = [
- { amount: "1000000", origin_asset: { decimals: 6, symbol: "INIT" } },
- { amount: "500", origin_asset: { decimals: 0, symbol: "USDC" } },
- ]
- // @ts-expect-error unused values are not defined
- expect(formatFees(fees)).toBe("1.000000 INIT, 500 USDC")
- })
-
- it("limits decimal places to 6", () => {
- const fees = [{ amount: "123456789", origin_asset: { decimals: 8, symbol: "ETH" } }]
- // @ts-expect-error unused values are not defined
- expect(formatFees(fees)).toBe("1.234567 ETH")
- })
-})
diff --git a/packages/interwovenkit-react/src/pages/bridge/data/format.ts b/packages/interwovenkit-react/src/pages/bridge/data/format.ts
--- a/packages/interwovenkit-react/src/pages/bridge/data/format.ts
+++ b/packages/interwovenkit-react/src/pages/bridge/data/format.ts
@@ -1,6 +1,4 @@
-import type { FeeJson } from "@skip-go/client"
import BigNumber from "bignumber.js"
-import { formatAmount } from "@initia/utils"
const TIME_UNIT_DEFINITIONS = [
["d", 24 * 60 * 60], // day
["h", 60 * 60], // hour
@@ -33,12 +31,3 @@
.integerValue(BigNumber.ROUND_FLOOR)
.toFixed(0)
}
-
-export function formatFees(fees?: FeeJson[]) {
- return fees
- ?.map((fee) => {
- const { amount, origin_asset } = fee
- return `${formatAmount(amount, { decimals: origin_asset.decimals ?? 0 })} ${origin_asset.symbol}`
- })
- .join(", ")
-}You can send follow-ups to this agent here.
Amp-Thread-ID: https://ampcode.com/threads/T-019d4ed4-e89d-7212-b4a7-dc76b55e1ae1 Co-authored-by: Amp <amp@ampcode.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/interwovenkit-react/src/pages/bridge/data/format.test.ts (1)
50-55: Test label/comments are inconsistent with the constructed duration.Line 50 mentions “weeks,” but the case asserts
1d 2h 3m 4s; and Lines 52-55 comments (“2 days”, “3 hours”, etc.) don’t match the multipliers. Please align wording/comments to prevent confusion.🧹 Suggested cleanup
- it("formats combined weeks, days, hours, minutes, seconds", () => { + it("formats combined days, hours, minutes, seconds", () => { const combinedSeconds = - 1 * 24 * 3600 + // 2 days - 2 * 3600 + // 3 hours - 3 * 60 + // 4 minutes - 4 // 5 seconds + 1 * 24 * 3600 + // 1 day + 2 * 3600 + // 2 hours + 3 * 60 + // 3 minutes + 4 // 4 seconds🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/interwovenkit-react/src/pages/bridge/data/format.test.ts` around lines 50 - 55, The test label in the it("formats combined weeks, days, hours, minutes, seconds", ...) does not match the constructed duration or inline comments; update the test name and comments to reflect the actual values (e.g., if you intend 1 day, 2 hours, 3 minutes, 4 seconds change the title to "formats combined days, hours, minutes, seconds" and fix the comment multipliers to 1*24*3600 // 1 day, 2*3600 // 2 hours, 3*60 // 3 minutes, 4 // 4 seconds) or alternatively adjust the numeric multipliers and comment text to include weeks if that was intended (modify the combinedSeconds expression accordingly). Ensure the test description, inline comments, and the combinedSeconds expression are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/interwovenkit-react/src/pages/bridge/data/format.test.ts`:
- Around line 50-55: The test label in the it("formats combined weeks, days,
hours, minutes, seconds", ...) does not match the constructed duration or inline
comments; update the test name and comments to reflect the actual values (e.g.,
if you intend 1 day, 2 hours, 3 minutes, 4 seconds change the title to "formats
combined days, hours, minutes, seconds" and fix the comment multipliers to
1*24*3600 // 1 day, 2*3600 // 2 hours, 3*60 // 3 minutes, 4 // 4 seconds) or
alternatively adjust the numeric multipliers and comment text to include weeks
if that was intended (modify the combinedSeconds expression accordingly). Ensure
the test description, inline comments, and the combinedSeconds expression are
consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 340f878e-8c55-4aaf-9662-992b7c88eacc
📒 Files selected for processing (7)
packages/interwovenkit-react/src/components/Dropdown.tsxpackages/interwovenkit-react/src/components/FormattedAmount.tsxpackages/interwovenkit-react/src/components/FormattedFeeList.tsxpackages/interwovenkit-react/src/lib/format.test.tspackages/interwovenkit-react/src/pages/bridge/data/format.test.tspackages/interwovenkit-react/src/pages/bridge/data/format.tspackages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
💤 Files with no reviewable changes (1)
- packages/interwovenkit-react/src/pages/bridge/data/format.ts
✅ Files skipped from review due to trivial changes (1)
- packages/interwovenkit-react/src/components/FormattedFeeList.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/interwovenkit-react/src/components/FormattedAmount.tsx
- packages/interwovenkit-react/src/lib/format.test.ts
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Leftover
getDpsuppresses subscript notation inTxFee- Removed the leftover
getDpoverride and unusedformatAmountBaseimport soTxFeenow letsFormattedAmountapply subscript notation consistently.
- Removed the leftover
Or push these changes by commenting:
@cursor push 92a9026b8a
Preview (92a9026b8a)
diff --git a/packages/interwovenkit-react/src/pages/tx/TxFee.tsx b/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
--- a/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
+++ b/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
@@ -1,6 +1,5 @@
import type { StdFee } from "@cosmjs/amino"
import BigNumber from "bignumber.js"
-import { formatAmount as formatAmountBase } from "@initia/utils"
import Dropdown, { type DropdownOption } from "@/components/Dropdown"
import FormattedAmount from "@/components/FormattedAmount"
import { useFindAsset } from "@/data/assets"
@@ -21,18 +20,12 @@
const chain = useChain(txRequest.chainId)
const findAsset = useFindAsset(chain)
- const getDp = (amount: string, decimals: number) => {
- if (formatAmountBase(amount, { decimals }) === "0.000000") return 8
- return undefined
- }
-
const getLabel = ({ amount: [{ amount, denom }] }: StdFee): ReactNode => {
if (BigNumber(amount).isZero()) return "0"
const { symbol, decimals } = findAsset(denom)
- const dp = getDp(amount, decimals)
return (
<>
- <FormattedAmount amount={amount} decimals={decimals} dp={dp} /> {symbol}
+ <FormattedAmount amount={amount} decimals={decimals} /> {symbol}
</>
)
}
@@ -57,11 +50,10 @@
const [{ amount, denom }] = selected.amount
const { decimals } = findAsset(denom)
- const dp = getDp(amount, decimals)
return (
<div className={styles.root}>
- <FormattedAmount amount={amount} decimals={decimals} dp={dp} className="monospace" />
+ <FormattedAmount amount={amount} decimals={decimals} className="monospace" />
<Dropdown options={dropdownOptions} value={value} onChange={onChange} classNames={styles} />
</div>
)You can send follow-ups to this agent here.
Amp-Thread-ID: https://ampcode.com/threads/T-019d4ed4-e89d-7212-b4a7-dc76b55e1ae1 Co-authored-by: Amp <amp@ampcode.com>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/interwovenkit-react/src/components/Scrollable.module.css (1)
2-8:⚠️ Potential issue | 🟡 MinorRemove the empty line before
min-heightto satisfy stylelint.Line 3 introduces an empty line before Line 4, which violates
declaration-empty-line-before.Proposed cleanup
.scrollable { flex: 1; - min-height: 0; overflow: hidden; -webkit-overflow-scrolling: touch; overflow-y: auto; overscroll-behavior: contain; padding: var(--padding); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/interwovenkit-react/src/components/Scrollable.module.css` around lines 2 - 8, Remove the stray blank line between the `flex: 1;` and `min-height: 0;` declarations in Scrollable.module.css to satisfy stylelint's declaration-empty-line-before rule; open the ruleset containing `flex: 1;`, delete the empty line so `min-height: 0;` immediately follows `flex: 1;`, then run stylelint to confirm the warning is resolved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/interwovenkit-react/src/components/Scrollable.module.css`:
- Around line 2-8: Remove the stray blank line between the `flex: 1;` and
`min-height: 0;` declarations in Scrollable.module.css to satisfy stylelint's
declaration-empty-line-before rule; open the ruleset containing `flex: 1;`,
delete the empty line so `min-height: 0;` immediately follows `flex: 1;`, then
run stylelint to confirm the warning is resolved.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6f267907-15f5-487c-a3a3-b9d3eab4e46d
📒 Files selected for processing (1)
packages/interwovenkit-react/src/components/Scrollable.module.css
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: ReactNode labels break Select keyboard text navigation
- Added explicit string typeahead labels for fee dropdown items so Base UI no longer derives garbled navigation text from ReactNode content.
Or push these changes by commenting:
@cursor push 9d38895e19
Preview (9d38895e19)
diff --git a/packages/interwovenkit-react/src/components/Dropdown.tsx b/packages/interwovenkit-react/src/components/Dropdown.tsx
--- a/packages/interwovenkit-react/src/components/Dropdown.tsx
+++ b/packages/interwovenkit-react/src/components/Dropdown.tsx
@@ -10,6 +10,7 @@
value: T
label: ReactNode
triggerLabel?: ReactNode
+ typeaheadLabel?: string
}
interface DropdownProps<T = string> {
@@ -23,6 +24,12 @@
}
}
+function getTypeaheadLabel<T>(option: DropdownOption<T>): string | undefined {
+ if (option.typeaheadLabel) return option.typeaheadLabel
+ if (typeof option.label === "string" || typeof option.label === "number")
+ return String(option.label)
+}
+
function Dropdown<T extends string | number = string>({
options,
value,
@@ -62,6 +69,7 @@
className={clsx(styles.item, classNames?.item)}
value={String(option.value)}
key={String(option.value)}
+ label={getTypeaheadLabel(option)}
>
<Select.ItemText className={clsx(styles.itemText, classNames?.itemText)}>
{option.label}
diff --git a/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx b/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
--- a/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
+++ b/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
@@ -3,6 +3,7 @@
import type { TxJson } from "@skip-go/client"
import BigNumber from "bignumber.js"
import { useState } from "react"
+import { formatAmount } from "@initia/utils"
import Dropdown, { type DropdownOption } from "@/components/Dropdown"
import FormattedAmount from "@/components/FormattedAmount"
import { useBalances } from "@/data/account"
@@ -202,12 +203,13 @@
if (!selectedFee || !feeDenom) return null
const dropdownOptions: DropdownOption<string>[] = feeOptions.map((option) => {
- const [{ denom }] = option.amount
- const { symbol } = findAsset(denom)
+ const [{ amount, denom }] = option.amount
+ const { symbol, decimals } = findAsset(denom)
return {
value: denom,
label: getFeeLabel(option),
+ typeaheadLabel: `${formatAmount(amount, { decimals })} ${symbol}`,
triggerLabel: symbol,
}
})
diff --git a/packages/interwovenkit-react/src/pages/tx/TxFee.tsx b/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
--- a/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
+++ b/packages/interwovenkit-react/src/pages/tx/TxFee.tsx
@@ -1,4 +1,5 @@
import type { StdFee } from "@cosmjs/amino"
+import { formatAmount } from "@initia/utils"
import Dropdown, { type DropdownOption } from "@/components/Dropdown"
import FormattedAmount from "@/components/FormattedAmount"
import { useFindAsset } from "@/data/assets"
@@ -29,12 +30,13 @@
}
const dropdownOptions: DropdownOption<string>[] = options.map((option) => {
- const [{ denom }] = option.amount
- const { symbol } = findAsset(denom)
+ const [{ amount, denom }] = option.amount
+ const { symbol, decimals } = findAsset(denom)
return {
value: denom,
label: getLabel(option),
+ typeaheadLabel: `${formatAmount(amount, { decimals })} ${symbol}`,
triggerLabel: symbol,
}
})You can send follow-ups to this agent here.
|
Addressed the unresolved review items in commit 80d780e:
Local verification run on this branch:
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Redundant inline reimplementation of
formatDisplayAmountPlainText- Replaced the duplicated inline formatting logic in
TransferFooter.tsxwith the sharedformatDisplayAmountPlainTexthelper.
- Replaced the duplicated inline formatting logic in
Or push these changes by commenting:
@cursor push ac05c21922
Preview (ac05c21922)
diff --git a/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx b/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
--- a/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
+++ b/packages/interwovenkit-react/src/pages/deposit/TransferFooter.tsx
@@ -9,7 +9,7 @@
import { useFindAsset } from "@/data/assets"
import { useChain } from "@/data/chains"
import { useGasPrices, useLastFeeDenom } from "@/data/fee"
-import { formatDisplayAmountParts } from "@/lib/format"
+import { formatDisplayAmountParts, formatDisplayAmountPlainText } from "@/lib/format"
import { DEFAULT_GAS_ADJUSTMENT } from "@/public/data/constants"
import BridgePreviewFooter from "../bridge/BridgePreviewFooter"
import { useAllSkipAssets } from "../bridge/data/assets"
@@ -195,10 +195,7 @@
const [{ amount, denom }] = fee.amount
const { symbol, decimals } = findAsset(denom)
const parts = formatDisplayAmountParts(amount, { decimals })
- const amountText =
- parts.kind === "plain"
- ? parts.value
- : `${parts.prefix}${"0".repeat(parts.hiddenZeroCount)}${parts.significant}`
+ const amountText = formatDisplayAmountPlainText(parts)
return `${amountText} ${symbol}`
}You can send follow-ups to this agent here.
|
Addressed follow-up review items in this branch:\n\n- Replaced inline fee search-label formatting in with the shared helper path.\n- Kept the existing shared format helper API consistent with tests and callers.\n- Normalized declaration spacing in and per stylelint suggestion.\n\nValidation run:\n- on touched files ✅\n- on touched TS/TSX ✅\n-
�[1m�[46m RUN �[49m�[22m �[36mv4.0.9 �[39m�[90m/private/tmp/interwovenkit-pr168-review/packages/interwovenkit-react�[39m �[32m✓�[39m src/data/clamm/calculateTokens.test.ts �[2m(�[22m�[2m4 tests�[22m�[2m)�[22m�[32m 4�[2mms�[22m�[39m �[2m Test Files �[22m �[1m�[32m44 passed�[39m�[22m�[90m (44)�[39m |
|
Addressed the unresolved low-severity review thread in Current unresolved threads are now only the two earlier CodeRabbit CSS spacing suggestions in CI snapshot is green on this head commit. |


Summary
This PR improves tiny-balance display so non-zero amounts that previously looked like
0.000000are shown with compact Unicode subscript notation (for example0.0₆3159).User impact
Users can now distinguish tiny non-zero balances from zero across bridge, asset selection, transfer, send, portfolio, activity, and fee surfaces while keeping the existing 6-decimal display budget.
Root cause
The previous formatter truncated many tiny values to zero-looking output. During refactors, the codebase also kept an exported structured-parts formatter path intended for HTML
<sub>rendering even though the UI intentionally renders Unicode subscript strings, andformatFeesinbridge/data/format.tsbecame dead production code.Changes
FormattedAmountand alignedlib/formatto that path.formatDisplayAmountPartsAPI and inlined it as an internal helper used only byformatDisplayAmount.formatFeesproduction utility frombridge/data/format.ts.formatFeestest cases frombridge/data/format.test.ts.Notes
This intentionally uses Unicode subscript glyphs (not HTML
<sub>) to match the requested visual style.Note
Medium Risk
Medium risk because it changes amount/fee rendering and dropdown search labels across many transaction and bridge flows; formatting or accessibility regressions could affect user decisions but no auth or data-write logic is touched.
Overview
Introduces
FormattedAmount(with accessible plain-text output) and a sharedformatDisplayAmountPartsformatter to show tiny non-zero values using compact Unicode subscript notation instead of appearing as0.000000.Replaces
formatAmount/formatFeesusage across bridge, deposit/transfer, tx approval/simulation, send, portfolio, and activity UI withFormattedAmount/FormattedFeeList, and removes the now-deadformatFeeshelper/tests. UpdatesDropdownoptions to acceptReactNodelabels and addssearchLabelsupport, plus minor layout fixes to scroll/page containers andQuantityInput.ReadOnlyplaceholder handling.Reviewed by Cursor Bugbot for commit a11ec46. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Refactor
Tests