Skip to content

Commit 9b3831d

Browse files
fix(dashboard): support more decimals for tx rates (#13407)
* Percentage formatter set maximum digits to 4 * Modify Tax Region Forms to allow 4 digits tax rates * Add changeset * Revert placeholder value to use only 2 decimals * fix(dashboard): support more decimals for tx rates * changeset * bypass scale * refactor * fix removal of deprecated input * cleanup deprecated percentage input * small mistake in onchange * add deprecated percentage input back * import * remove file extension * frane comment --------- Co-authored-by: AmbroziuBaban <[email protected]>
1 parent 0000ed6 commit 9b3831d

File tree

10 files changed

+102
-41
lines changed

10 files changed

+102
-41
lines changed

.changeset/large-months-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/dashboard": patch
3+
---
4+
5+
fix(dashboard): support more decimals for tx rates
Lines changed: 67 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1-
import { Input, Text, clx } from "@medusajs/ui"
1+
import { clx, Input, Text } from "@medusajs/ui"
2+
import { getNumberOfDecimalPlaces } from "../../../lib/number-helper"
23
import { ComponentProps, ElementRef, forwardRef } from "react"
34
import Primitive from "react-currency-input-field"
45

5-
/**
6-
* @deprecated Use `PercentageInput` instead
7-
*/
6+
const MIN_DECIMAL_SCALE = 2
7+
8+
function resolveDecimalScale(
9+
value: string | readonly string[] | number | undefined | null
10+
): number | undefined {
11+
if (value == null || Array.isArray(value)) {
12+
return MIN_DECIMAL_SCALE
13+
}
14+
return Math.max(
15+
getNumberOfDecimalPlaces(parseFloat(value.toString())),
16+
MIN_DECIMAL_SCALE
17+
)
18+
}
19+
820
export const DeprecatedPercentageInput = forwardRef<
921
ElementRef<typeof Input>,
1022
Omit<ComponentProps<typeof Input>, "type">
@@ -38,38 +50,56 @@ DeprecatedPercentageInput.displayName = "PercentageInput"
3850
export const PercentageInput = forwardRef<
3951
ElementRef<"input">,
4052
ComponentProps<typeof Primitive>
41-
>(({ min = 0, decimalScale = 2, className, ...props }, ref) => {
42-
return (
43-
<div className="relative">
44-
<Primitive
45-
ref={ref as any} // dependency is typed incorrectly
46-
min={min}
47-
autoComplete="off"
48-
decimalScale={decimalScale}
49-
decimalsLimit={decimalScale}
50-
{...props}
51-
className={clx(
52-
"caret-ui-fg-base bg-ui-bg-field shadow-buttons-neutral transition-fg txt-compact-small flex w-full select-none appearance-none items-center justify-between rounded-md px-2 py-1.5 pr-10 text-right outline-none",
53-
"placeholder:text-ui-fg-muted text-ui-fg-base",
54-
"hover:bg-ui-bg-field-hover",
55-
"focus-visible:shadow-borders-interactive-with-active data-[state=open]:!shadow-borders-interactive-with-active",
56-
"aria-[invalid=true]:border-ui-border-error aria-[invalid=true]:shadow-borders-error",
57-
"invalid::border-ui-border-error invalid:shadow-borders-error",
58-
"disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
59-
className
60-
)}
61-
/>
62-
<div className="absolute inset-y-0 right-0 z-10 flex w-8 items-center justify-center border-l">
63-
<Text
64-
className="text-ui-fg-muted"
65-
size="small"
66-
leading="compact"
67-
weight="plus"
68-
>
69-
%
70-
</Text>
53+
>(
54+
(
55+
{
56+
min = 0,
57+
max = 100,
58+
decimalScale,
59+
decimalsLimit,
60+
value,
61+
className,
62+
...props
63+
},
64+
ref
65+
) => {
66+
const resolvedDecimalScale = decimalScale ?? resolveDecimalScale(value)
67+
const resolvedDecimalsLimit = decimalsLimit ?? resolvedDecimalScale
68+
69+
return (
70+
<div className="relative">
71+
<Primitive
72+
ref={ref as any} // dependency is typed incorrectly
73+
min={min}
74+
max={max}
75+
autoComplete="off"
76+
decimalScale={resolvedDecimalScale}
77+
decimalsLimit={resolvedDecimalsLimit}
78+
value={value}
79+
{...props}
80+
className={clx(
81+
"caret-ui-fg-base bg-ui-bg-field shadow-buttons-neutral transition-fg txt-compact-small flex w-full select-none appearance-none items-center justify-between rounded-md px-2 py-1.5 pl-10 text-left outline-none",
82+
"placeholder:text-ui-fg-muted text-ui-fg-base",
83+
"hover:bg-ui-bg-field-hover",
84+
"focus-visible:shadow-borders-interactive-with-active data-[state=open]:!shadow-borders-interactive-with-active",
85+
"aria-[invalid=true]:border-ui-border-error aria-[invalid=true]:shadow-borders-error",
86+
"invalid::border-ui-border-error invalid:shadow-borders-error",
87+
"disabled:!bg-ui-bg-disabled disabled:!text-ui-fg-disabled",
88+
className
89+
)}
90+
/>
91+
<div className="absolute inset-y-0 left-0 z-10 flex w-8 items-center justify-center border-r">
92+
<Text
93+
className="text-ui-fg-muted"
94+
size="small"
95+
leading="compact"
96+
weight="plus"
97+
>
98+
%
99+
</Text>
100+
</div>
71101
</div>
72-
</div>
73-
)
74-
})
102+
)
103+
}
104+
)
75105
PercentageInput.displayName = "PercentageInput"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Gets the number of decimal places in a number
3+
* @param num - The number for which we are getting the number of decimal places
4+
* @returns The number of decimal places
5+
*
6+
* @example
7+
* getDecimalPlaces(123.456) // 3
8+
* getDecimalPlaces(42) // 0
9+
* getDecimalPlaces(10.0000) // 0
10+
*/
11+
export function getNumberOfDecimalPlaces(num: number): number {
12+
// Convert to string and check if it contains a decimal point
13+
const str = num.toString()
14+
if (str.indexOf(".") === -1) {
15+
return 0
16+
}
17+
// Return the length of the part after the decimal point
18+
return str.split(".")[1].length
19+
}

packages/admin/dashboard/src/lib/percentage-helpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const formatter = new Intl.NumberFormat([], {
22
style: "percent",
33
minimumFractionDigits: 2,
4+
maximumFractionDigits: 4,
45
})
56

67
/**

packages/admin/dashboard/src/routes/tax-regions/tax-region-create/components/tax-region-create-form/tax-region-create-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useForm } from "react-hook-form"
33
import { z } from "zod"
44

55
import { InformationCircleSolid } from "@medusajs/icons"
6-
import { Button, Heading, Input, Text, Tooltip, toast } from "@medusajs/ui"
6+
import { Button, Heading, Input, Text, toast, Tooltip } from "@medusajs/ui"
77
import { useTranslation } from "react-i18next"
88
import { Form } from "../../../../../components/common/form"
99
import { CountrySelect } from "../../../../../components/inputs/country-select"
@@ -221,6 +221,7 @@ export const TaxRegionCreateForm = ({ parentId }: TaxRegionCreateFormProps) => {
221221
<PercentageInput
222222
{...field}
223223
value={value?.value}
224+
decimalsLimit={4}
224225
onValueChange={(value, _name, values) =>
225226
onChange({
226227
value: value,

packages/admin/dashboard/src/routes/tax-regions/tax-region-province-create/components/tax-region-province-create-form/tax-region-province-create-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { zodResolver } from "@hookform/resolvers/zod"
22
import { InformationCircleSolid } from "@medusajs/icons"
33
import { HttpTypes } from "@medusajs/types"
4-
import { Button, Heading, Input, Text, Tooltip, toast } from "@medusajs/ui"
4+
import { Button, Heading, Input, Text, toast, Tooltip } from "@medusajs/ui"
55
import { useForm } from "react-hook-form"
66
import { useTranslation } from "react-i18next"
77
import { z } from "zod"
@@ -189,6 +189,7 @@ export const TaxRegionProvinceCreateForm = ({
189189
<PercentageInput
190190
{...field}
191191
value={value?.value}
192+
decimalsLimit={4}
192193
onValueChange={(value, _name, values) =>
193194
onChange({
194195
value: value,

packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-create/components/tax-region-override-create-form/tax-region-tax-override-create.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { zodResolver } from "@hookform/resolvers/zod"
22
import {
33
Button,
4+
clx,
45
Divider,
56
Heading,
67
Hint,
78
Input,
89
Label,
910
Select,
1011
Text,
11-
clx,
1212
toast,
1313
} from "@medusajs/ui"
1414
import { useFieldArray, useForm, useWatch } from "react-hook-form"
@@ -414,6 +414,7 @@ export const TaxRegionCreateTaxOverrideForm = ({
414414
<PercentageInput
415415
{...field}
416416
placeholder="0.00"
417+
decimalsLimit={4}
417418
value={value?.value}
418419
onValueChange={(value, _name, values) =>
419420
onChange({

packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-override-edit/components/tax-region-tax-override-edit-form/tax-region-tax-override-edit-form.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { MagnifyingGlass } from "@medusajs/icons"
33
import { HttpTypes } from "@medusajs/types"
44
import {
55
Button,
6+
clx,
67
Divider,
78
Heading,
89
Hint,
910
Input,
1011
Label,
1112
Select,
1213
Text,
13-
clx,
1414
toast,
1515
} from "@medusajs/ui"
1616
import { useFieldArray, useForm, useWatch } from "react-hook-form"
@@ -414,6 +414,7 @@ export const TaxRegionTaxOverrideEditForm = ({
414414
<PercentageInput
415415
{...field}
416416
value={value?.value}
417+
decimalsLimit={4}
417418
onValueChange={(value, _name, values) =>
418419
onChange({
419420
value: value,

packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-rate-create/components/tax-region-tax-rate-create-form/tax-region-tax-rate-create-form.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export const TaxRegionTaxRateCreateForm = ({
119119
<PercentageInput
120120
{...field}
121121
value={value?.value}
122+
decimalsLimit={4}
122123
onValueChange={(value, _name, values) =>
123124
onChange({
124125
value: value,

packages/admin/dashboard/src/routes/tax-regions/tax-region-tax-rate-edit/components/tax-region-tax-rate-edit-form/tax-region-tax-rate-edit-form.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ export const TaxRegionTaxRateEditForm = ({
117117
<PercentageInput
118118
{...field}
119119
value={value?.value}
120+
decimalsLimit={4}
120121
onValueChange={(value, _name, values) =>
121122
onChange({
122123
value: value,

0 commit comments

Comments
 (0)