Skip to content

Comments

Price input: Get rid of stepper, improve validation, and use Text instead of Numeric input#6307

Draft
mirekm wants to merge 4 commits intomainfrom
fix/update-money-input
Draft

Price input: Get rid of stepper, improve validation, and use Text instead of Numeric input#6307
mirekm wants to merge 4 commits intomainfrom
fix/update-money-input

Conversation

@mirekm
Copy link
Member

@mirekm mirekm commented Jan 31, 2026

Reasons for updating it:

  • I see no use case for the stepper
  • The current validation is slow and laggy (likely a combination of Numeric and current custom validation code)
  • It would be nice to support display formatting (like 1,223.22) when value is copeid in

Copilot AI review requested due to automatic review settings January 31, 2026 18:31
@changeset-bot
Copy link

changeset-bot bot commented Jan 31, 2026

⚠️ No Changeset found

Latest commit: 1944a85

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors monetary and percentage inputs to rely on text-based inputs with shared formatting utilities, removes numeric input spinners, and tightens validation/normalization for prices and tax rates.

Changes:

  • Replace type="number" price/tax inputs with text inputs (inputMode="decimal") and route all price handling through PriceField + usePriceField, now backed by formatPriceInput / formatPercentInput.
  • Normalize the PriceField and TaxInput APIs (named exports, consistent onChange event shape) and update all call sites to work with the new event/value model.
  • Add comprehensive unit tests for the new price/percent formatting utilities and simplify currency decimal resolution logic.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/taxes/pages/TaxCountriesPage/TaxCountriesPage.tsx Switch TaxInput import to named export to match the new TaxInput module API.
src/taxes/pages/TaxClassesPage/TaxClassesPage.tsx Same TaxInput import adjustment as above for the tax classes page.
src/taxes/components/TaxInput/index.ts Change TaxInput exports to a named export (export { TaxInput }) for consistency.
src/taxes/components/TaxInput/TaxInput.tsx Rework TaxInput to use a text input with formatPercentInput, removing custom separator logic and numeric field spinners.
src/shipping/components/PricingCard/PricingCard.tsx Update to named PriceField import; behavior otherwise unchanged.
src/shipping/components/OrderValue/OrderValue.tsx Update to named PriceField import and adjust channel minValue/maxValue handlers to accept `string
src/products/components/ProductVariantPrice/ProductVariantPrice.tsx Use named PriceField import and update per-channel pricing handlers to consume the new string-based price value.
src/orders/components/OrderSendRefundPage/components/TransactionCard.tsx Use named PriceField import and keep existing numeric parsing of e.target.value (now coming from the formatted string).
src/orders/components/OrderReturnPage/components/TransactionSubmitCard/TransactionSubmitCard.tsx Adjust refund value input to parse the formatted PriceField value via `parseFloat(e.target.value ?? "")
src/orders/components/OrderReturnPage/components/PaymentSubmitCard/RefundAmountInput.tsx Update to named PriceField import; onChange still forwards the event into the refund form logic.
src/orders/components/OrderManualTransactionForm/hooks.ts Change manual refund handleChangeAmount to accept the new PriceField event shape ({ target: { value: string | null } }) and parse it to a number.
src/orders/components/OrderManualTransactionForm/components/PriceInputField.tsx Wire PriceField directly to the manual transaction context’s handleChangeAmount and amount using the new props/types.
src/orders/components/OrderGrantRefundPage/OrderGrantRefundPage.tsx Use named PriceField import; rely on useGrantRefundForm.change to receive the new normalized price value.
src/orders/components/OrderDiscountCommonModal/OrderDiscountCommonModal.tsx Use named PriceField and update handleSetDiscountValue to accept the new event type and validate the string value before parsing.
src/orders/components/OrderCaptureDialog/OrderCaptureDialog.tsx Replace legacy decimal helpers with formatPriceInput for capture amount, then parse with parseFloat, keeping currency-aware decimal precision via getCurrencyDecimalPoints.
src/discounts/components/VoucherRequirements/VoucherRequirements.tsx Swap to named PriceField import and continue to pass per-channel minimum spend as a string driven by the new formatter.
src/components/PriceField/utils.ts Replace old normalization utilities with formatPercentInput and formatPriceInput, and simplify getCurrencyDecimalPoints implementation.
src/components/PriceField/utils.test.ts Rewrite tests to cover the new formatting logic for prices and percentages, including locale-style inputs, paste cases, and edge conditions.
src/components/PriceField/usePriceField.ts Simplify to a single onChange handler that runs formatPriceInput and passes a { target: { name, value: string | null } } event to consumers.
src/components/PriceField/index.ts Replace default export with named PriceField and re-export PriceFieldProps type.
src/components/PriceField/consts.ts Remove obsolete separator constants now that formatting is handled centrally.
src/components/PriceField/PriceField.tsx Make PriceField a named component; switch to text input + inputMode="decimal", accept a custom onChange signature, and route changes through usePriceField.
src/components/Datagrid/customCells/Money/MoneyCell.tsx Replace usePriceField with a plain <input type="number">, using getCurrencyDecimalPoints only for step and local parsing/keyboard filtering for editing.
.github/workflows/publish-containers.yml Remove stray blank lines for minor workflow formatting cleanup.

Comment on lines +26 to 38
const maxDecimalPlaces = useMemo(
() => getCurrencyDecimalPoints(cell.data.currency),
[cell.data.currency],
);
const step = 1 / Math.pow(10, maxDecimalPlaces ?? 2);

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
onChangeBase({
...cell,
data: {
...cell.data,
value: event.target.value,
value: e.target.value ? parseFloat(e.target.value) : null,
},
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

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

The previous implementation relied on usePriceField to enforce currency-specific decimal precision (including blocking decimal input for zero-decimal currencies like JPY) and to normalize pasted values with locale-specific separators. The new MoneyCellEdit now only uses step and a basic parseFloat, so maxDecimalPlaces is not actually used to constrain the input and users can enter more fractional digits than the currency allows (and even fractions for zero-decimal currencies), which is inconsistent with PriceField and may lead to invalid values being submitted. Consider either reusing formatPriceInput/usePriceField here or applying similar decimal-length trimming inside handleChange so that the datagrid editor respects maxDecimalPlaces in the same way as other price inputs.

Copilot uses AI. Check for mistakes.
@mirekm mirekm changed the title Get rid of spinner, improve validation, and use Text instead of Numeric input Get rid of stepper, improve validation, and use Text instead of Numeric input Jan 31, 2026
@mirekm mirekm changed the title Get rid of stepper, improve validation, and use Text instead of Numeric input Price input: Get rid of stepper, improve validation, and use Text instead of Numeric input Jan 31, 2026
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.

1 participant