Skip to content

feat: migrate NumericTextInput to Blend Design System#4641

Open
kanikabansal08 wants to merge 4 commits intomainfrom
blend-phase2-numericinput
Open

feat: migrate NumericTextInput to Blend Design System#4641
kanikabansal08 wants to merge 4 commits intomainfrom
blend-phase2-numericinput

Conversation

@kanikabansal08
Copy link
Copy Markdown
Collaborator

@kanikabansal08 kanikabansal08 commented Mar 31, 2026

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

Migrates NumericTextInput to Blend Design System behind the devBlendEnabled feature flag.
Adds NumberInputBinding.res (raw Blend binding) and NumericTextInputAdapter.res (feature-flagged
adapter). Dead props (~type_, ~pattern, ~autoComplete, ~min, ~max,
~widthMatchwithPlaceholderLength, ~iconOpacity, ~shouldSubmitForm, ~removeValidationCheck)
are removed from the adapter signature — all live props are preserved.

Closes #4642

Motivation and Context

Part of the incremental Blend Design System migration. The adapter routes all 27 call sites
(4 direct + 23 via InputFields.numericTextInput factory) through Blend when devBlendEnabled=true,
with a clean legacy fallback. Precision and removeLeadingZeroes logic is preserved in the Blend branch.

How did you test it?

Tested manually with devBlendEnabled toggled on and off across all 27 call sites:

Area Location
Orders / Transactions Orders table → amount filter (min/max fields)
Orders / Transactions Amount filter fields (AmountFilter, AmountFilterUtils)
Routing Advanced routing → volume-based numeric value fields
Routing Auth rate routing → percentage fields
Connectors Configure PMTs → numeric limit fields
Connectors Connector setup → numeric fields
Developer Payment settings → acquirer config (legacy + revamped)
Developer API keys → numeric fields
Developer SDK playground → amount fields
Revenue Recovery Billing processors → setup numeric fields
Payment Links Theme configurator → numeric fields

Where to test it?

  • INTEG
  • SANDBOX
  • PROD

Checklist

  • I ran npm run re:build
  • I reviewed submitted code
  • I added unit tests for my changes where possible

@kanikabansal08 kanikabansal08 requested a review from a team as a code owner March 31, 2026 10:27
@semanticdiff-com
Copy link
Copy Markdown

Review changes with  SemanticDiff

@muditbhutani
Copy link
Copy Markdown
Collaborator

@product-manager what do you think

@hs-control-center-bot
Copy link
Copy Markdown
Collaborator

Product Manager Analysis (powered by Claude)

Let me read the main adapter file to understand the implementation fully.
This is a remote PR review — let me work with the diff context provided.
Here's my analysis for the PR comment:


Solid, well-scoped migration. This follows the established adapter + feature flag pattern from the Accordion migration (#4405), which is the right incremental approach for the Blend rollout.

What's good

  • Feature flag gating via devBlendEnabled — zero risk to production users; Blend behavior is opt-in only.
  • Single adapter covers all 27 call sites — the InputFields.numericTextInput factory means only 4 files need updating despite 27 usages. Good leverage.
  • Dead prop cleanup — removing 9 unused props (~type_, ~pattern, ~autoComplete, ~min, ~max, etc.) from the adapter signature is the right call. Keeps the API surface clean rather than carrying legacy baggage.
  • Precision and removeLeadingZeroes logic preserved — these are load-bearing for amount fields (routing percentages, order amount filters), and the adapter reimplements them correctly for the Blend branch.

Concerns to address

  1. Precision logic has a subtle bug path. In the adapter (lines ~50-57), when precision is Some(val) but indexOfDec is 0 (user types .5), the slice works correctly. But when indexOfDec is -1 (no decimal), precisionCheckedVal becomes "" and falls through — which is fine. However, when precision is Some(0) (zero decimal places), a value like "42." would get sliced to "42." (indexOfDec=2, end=2+0+1=3), leaving a trailing dot. Worth adding a test case for integer-only fields.

  2. OTP adapter is bundled in but not in the issue scope. The PR description and linked issue feat: migrate NumericTextInput to Blend Design System #4642 are exclusively about NumericTextInput, but this also ships OTPInputAdapter.res and OTPInputBinding.res with the TwoFaElements.res change. This should either be called out in the PR description or split into its own PR for clean traceability. If it stays bundled, update the issue description.

  3. No unit tests. The checklist acknowledges "I added unit tests where possible" is unchecked. Given the custom precision/leading-zero logic in the Blend branch is hand-rolled (not delegated to the Blend component), this is the one place where tests would pay for themselves. The legacy NumericTextInput presumably had this logic internally — the adapter is now owning it, so it should own the test coverage too.

  4. leftIcon, rightIcon, customPaddingClass, customStyle are passed to legacy but ignored by Blend. This is expected during migration, but worth a code comment noting these props have no Blend equivalent yet, so reviewers six months from now don't wonder if it's an oversight.

  5. RouteUtils.res whitespace-only change (removing a blank line) — harmless but shouldn't be in this PR. Probably accidental from an editor auto-format.

Recommendation

Approve with minor changes:

  • Split or document the OTP adapter inclusion
  • Add at least one test for the precision + leading-zero logic in the Blend branch
  • Drop the RouteUtils.res noise change

The pattern is proven, the scope is tight, and the flag-gating makes this safe to ship. Good work by @kanikabansal08.

@kanikabansal08
Copy link
Copy Markdown
Collaborator Author

@control_center_review_bot please review this pr

@@ -0,0 +1,85 @@
let getFloat = strJson => strJson->JSON.Decode.string->Option.flatMap(val => val->Float.fromString)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚨 Logic duplication detected — getFloat is defined identically in both NumericTextInput.res:1 and this adapter.

Remove the local definition and import from the existing module to maintain a single source of truth.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where should I maintain this single source of truth @control_center_review_bot

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@control_center_review_bot where should I maintain this single source of truth

let getFloat = strJson => strJson->JSON.Decode.string->Option.flatMap(val => val->Float.fromString)

@react.component
let make = (
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Several props accepted by the adapter are silently dropped in the Blend branch:

  • customStyle
  • inputMode
  • leftIcon / rightIcon
  • customPaddingClass
  • leftIconCustomStyle / rightIconCustomStyle

These are all forwarded to NumericTextInput in the else branch (lines 69–83), but NumberInputBinding only receives value, onChange, disabled, placeholder, and maxLength.

Verify whether this is intentional — if Blend's NumberInput doesn't support these props, document that limitation. If it does, forward them consistently to avoid behavioral differences between branches.

let blendValue =
input.value->JSON.Decode.float->Option.mapOr(Nullable.null, f => Nullable.make(f))

let blendOnChange = ev => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Numeric parsing logic (lines 28–62) duplicates NumericTextInput.res:58–94 almost exactly — regex cleaning, decimal handling, precision slicing, and leading-zero removal.

Extract this to a shared utility or confirm why it must remain duplicated. If the logic diverges later, maintenance becomes risky.

~input: ReactFinalForm.fieldRenderPropsInput,
~placeholder,
~isDisabled=false,
~inputMode="number",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 inputMode is declared as a prop but never referenced in the Blend branch.

Since it's only passed to the legacy NumericTextInput, consider removing it from the adapter's signature if Blend's NumberInput doesn't support it, or pass it through if it does.

@@ -0,0 +1,12 @@
@react.component
let make = (~value: string, ~setValue: (string => string) => unit, ~hasError: bool=false) => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 OTPInputAdapter accepts hasError but the binding uses error (different prop name).

Confirm the Blend OTPInput component accepts error and that this mapping is intentional. If Blend uses a different prop naming convention, this could silently fail to display error states.

@@ -8,7 +8,6 @@ open UserInfoTypes
* RouteUtils.getPath(~path="/payments", version)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Whitespace-only change detected — this is a formatting change with no functional impact.

Keep formatting-only changes in a separate PR to keep diffs focused and reviews efficient.

Copy link
Copy Markdown
Collaborator

@hs-control-center-bot hs-control-center-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 🔄 Request Changes

🚨 1 critical · ⚠️ 3 warning · 🔍 2 nitpick

The adapter pattern implementation is sound, but there's significant code duplication between the new adapter and the existing NumericTextInput component. The getFloat helper and the numeric parsing logic (regex cleaning, decimal handling, precision slicing) should be extracted to a shared utility. Additionally, several props are silently dropped in the Blend branch, which could cause behavioral inconsistencies between feature flag states.

@hs-control-center-bot
Copy link
Copy Markdown
Collaborator

❔ Can't tell what to update from this thread.

The comment 'please update the skills' doesn't reference a specific finding or explain what rule needs changing.

Reply to a specific finding you want changed with a short note on what's wrong, then mention me again with 'update the skill' or '/update'.

@juspay juspay deleted a comment from KanikaBansal9 Apr 9, 2026
@juspay juspay deleted a comment from KanikaBansal9 Apr 9, 2026
@kanikabansal08
Copy link
Copy Markdown
Collaborator Author

@control_center_review_bot it instead of saying Remove the local definition and import from the existing module to maintain a single source of truth, we can say these type of things can go in logic utils.
please update the skill.

@hs-control-center-bot
Copy link
Copy Markdown
Collaborator

📝 Updated the reviewer based on this thread.

Change: Softened the phrasing for logic duplication findings. Instead of prescriptive "Remove the local definition and import", the skill now suggests "consider whether this logic belongs in a shared utility" or importing if already in a utility file.

Logical file: pr-reviewer/checklist.md and example in pr-reviewer/SKILL.md

Applied to: runtime copy (~/.config/opencode/skills/...) AND repo copy (/home/phoenix/repos/hyperswitch-control-center/.opencode/skills/...)

Runtime copy takes effect on the next review. Repo copy is uncommitted — a maintainer needs to land it so it survives the next redeploy.

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.

feat: migrate NumericTextInput to Blend Design System

3 participants