diff --git a/modules/core/src/common/helpers/number-helper.ts b/modules/core/src/common/helpers/number-helper.ts index 71ef4834..e7d95c50 100644 --- a/modules/core/src/common/helpers/number-helper.ts +++ b/modules/core/src/common/helpers/number-helper.ts @@ -1,3 +1,7 @@ -export const toSafeNumber = (value: number | null | undefined): number => { +const toSafeNumber = (value: number | null | undefined): number => { return value ?? 0; }; + +export const NumberHelper = { + toSafeNumber, +}; diff --git a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx index 36939e1a..3f2149cd 100644 --- a/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx +++ b/modules/customer-invoices/src/web/proformas/list/ui/blocks/proformas-grid/use-proforma-grid-columns.tsx @@ -230,8 +230,6 @@ export function useProformasGridColumns( const availableTransitions = PROFORMA_STATUS_TRANSITIONS[proforma.status as ProformaStatus] ?? []; - console.log(availableTransitions, proforma.status); - return (
{!isIssued && actionHandlers.onEditClick && ( diff --git a/modules/customer-invoices/src/web/proformas/shared/adapters/get-proforma-by-id.adapter.ts b/modules/customer-invoices/src/web/proformas/shared/adapters/get-proforma-by-id.adapter.ts index 7de7c5c8..04530f56 100644 --- a/modules/customer-invoices/src/web/proformas/shared/adapters/get-proforma-by-id.adapter.ts +++ b/modules/customer-invoices/src/web/proformas/shared/adapters/get-proforma-by-id.adapter.ts @@ -68,7 +68,7 @@ export const GetProformaByIdAdapter = { const mapItem = (dto: GetProformaByIdResponseDTO["items"][number]): ProformaItem => { return { id: dto.id, - position: dto.position, + position: Number(dto.position), description: dto.description, quantity: QuantityDTOHelper.toNumber(dto.quantity), diff --git a/modules/customer-invoices/src/web/proformas/shared/adapters/proforma-to-list-row-patch.adapter.ts b/modules/customer-invoices/src/web/proformas/shared/adapters/proforma-to-list-row-patch.adapter.ts index c2ef7432..217b25a0 100644 --- a/modules/customer-invoices/src/web/proformas/shared/adapters/proforma-to-list-row-patch.adapter.ts +++ b/modules/customer-invoices/src/web/proformas/shared/adapters/proforma-to-list-row-patch.adapter.ts @@ -19,7 +19,6 @@ export const ProformaToListRowPatchAdapter = { fromProforma(proforma: Proforma): ProformaListRowPatch { return { id: proforma.id, - customerId: proforma.customerId, invoiceNumber: proforma.invoiceNumber, status: proforma.status, series: proforma.series, @@ -29,10 +28,19 @@ export const ProformaToListRowPatchAdapter = { currencyCode: proforma.currencyCode, reference: proforma.reference, description: proforma.description, - recipientName: proforma.recipient.name, - recipientTin: proforma.recipient.tin, + recipient: { + id: proforma.customerId, + tin: proforma.recipient.tin, + name: proforma.recipient.name, + street: proforma.recipient.street, + street2: proforma.recipient.street2, + city: proforma.recipient.city, + province: proforma.recipient.province, + postalCode: proforma.recipient.postalCode, + country: proforma.recipient.country, + }, subtotalAmount: proforma.subtotalAmount, - discountPercentage: proforma.discountPercentage, + discountPercentage: proforma.globalDiscountPercentage, discountAmount: proforma.discountAmount, taxableAmount: proforma.taxableAmount, taxesAmount: proforma.taxesAmount, diff --git a/modules/customer-invoices/src/web/proformas/shared/entities/proforma-item.entity.ts b/modules/customer-invoices/src/web/proformas/shared/entities/proforma-item.entity.ts index 07bbe68c..4b1ba718 100644 --- a/modules/customer-invoices/src/web/proformas/shared/entities/proforma-item.entity.ts +++ b/modules/customer-invoices/src/web/proformas/shared/entities/proforma-item.entity.ts @@ -6,7 +6,7 @@ export interface ProformaItem { id: string; - position: string; + position: number; description: string; quantity: number; diff --git a/modules/customer-invoices/src/web/proformas/update/adapters/proforma-items-to-proforma-items-update-form.adapter.ts b/modules/customer-invoices/src/web/proformas/update/adapters/proforma-items-to-proforma-items-update-form.adapter.ts new file mode 100644 index 00000000..24a29cd4 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/update/adapters/proforma-items-to-proforma-items-update-form.adapter.ts @@ -0,0 +1,22 @@ +import type { ProformaItem } from "../../shared"; +import type { ProformaItemUpdateForm } from "../entities"; + +/** + * Mapea un cliente a un formulario de actualización de cliente. + * + * @param proforma + * @returns + */ + +export const mapProformaItemsToProformaItemsUpdateForm = ( + item: ProformaItem +): ProformaItemUpdateForm => { + return { + id: item.id, + position: item.position, + description: item.description, + quantity: item.quantity, + unitAmount: item.unitAmount, + itemDiscountPercentage: item.itemDiscountPercentage, + }; +}; diff --git a/modules/customer-invoices/src/web/proformas/update/adapters/proforma-to-proforma-update-form.adapter.ts b/modules/customer-invoices/src/web/proformas/update/adapters/proforma-to-proforma-update-form.adapter.ts index 869c160a..30fa0d07 100644 --- a/modules/customer-invoices/src/web/proformas/update/adapters/proforma-to-proforma-update-form.adapter.ts +++ b/modules/customer-invoices/src/web/proformas/update/adapters/proforma-to-proforma-update-form.adapter.ts @@ -1,6 +1,8 @@ import type { Proforma } from "../../shared"; import type { ProformaUpdateForm } from "../entities"; +import { mapProformaItemsToProformaItemsUpdateForm } from "./proforma-items-to-proforma-items-update-form.adapter"; + /** * Mapea un cliente a un formulario de actualización de cliente. * @@ -27,5 +29,7 @@ export const mapProformaToProformaUpdateForm = (proforma: Proforma): ProformaUpd globalDiscountPercentage: proforma.globalDiscountPercentage ?? 0, paymentMethod: proforma.paymentMethod ?? "", + + items: proforma.items.map(mapProformaItemsToProformaItemsUpdateForm), }; }; diff --git a/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-controller.ts b/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-controller.ts index 1251f5ba..9695d1f0 100644 --- a/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-controller.ts +++ b/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-controller.ts @@ -9,12 +9,9 @@ import type { UpdateProformaByIdParams } from "../../shared"; import type { Proforma } from "../../shared/entities"; import { useProformaGetQuery, useProformaUpdateMutation } from "../../shared/hooks"; import { mapProformaToProformaUpdateForm, mapProformaToSelectedCustomer } from "../adapters"; +import { type ProformaUpdateForm, ProformaUpdateFormSchema } from "../entities"; import { - type ProformaUpdateForm, - ProformaUpdateFormSchema, - defaultProformaUpdateForm, -} from "../entities"; -import { + buildProformaUpdateDefault, buildProformaUpdatePatch, buildUpdateProformaByIdParams, focusFirstProformaUpdateError, @@ -54,7 +51,7 @@ export const useUpdateProformaController = ( } = useProformaUpdateMutation(); const initialValues = useMemo(() => { - if (!proformaData) return defaultProformaUpdateForm; + if (!proformaData) return buildProformaUpdateDefault(); return mapProformaToProformaUpdateForm(proformaData); }, [proformaData]); @@ -84,7 +81,7 @@ export const useUpdateProformaController = ( const resetForm = () => { const initialData = proformaData ? mapProformaToProformaUpdateForm(proformaData) - : defaultProformaUpdateForm; + : buildProformaUpdateDefault(); form.reset(initialData, { keepDirty: false }); setSelectedCustomer(mapProformaToSelectedCustomer(proformaData)); @@ -120,6 +117,9 @@ export const useUpdateProformaController = ( const previousData = proformaData; const patchData = buildProformaUpdatePatch(formData, form.formState.dirtyFields); + + console.log(patchData); + const params = buildUpdateProformaByIdParams(proformaId, patchData); try { @@ -147,7 +147,9 @@ export const useUpdateProformaController = ( error instanceof Error ? error : new Error(t("pages.update.error.unknown")); form.reset( - previousData ? mapProformaToProformaUpdateForm(previousData) : defaultProformaUpdateForm, + previousData + ? mapProformaToProformaUpdateForm(previousData) + : buildProformaUpdateDefault(), { keepDirty: false } ); @@ -159,6 +161,7 @@ export const useUpdateProformaController = ( } }, (errors: FieldErrors) => { + console.log(errors); focusFirstProformaUpdateError(errors); showWarningToast( diff --git a/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-items-controller.ts b/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-items-controller.ts index 5fed0f57..02ee49d8 100644 --- a/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-items-controller.ts +++ b/modules/customer-invoices/src/web/proformas/update/controllers/use-update-proforma-items-controller.ts @@ -1,3 +1,4 @@ +import { NumberHelper } from "@erp/core"; import * as React from "react"; import { type FieldArrayWithId, @@ -7,11 +8,11 @@ import { } from "react-hook-form"; import type { ProformaItemUpdateForm, ProformaUpdateForm } from "../entities"; -import { buildProformaItemUpdateDefault } from "../utils/build-proforma-item-update-default"; +import { buildProformaItemUpdateDefault } from "../utils"; export interface ProformaItemAmounts { subtotal: number; - discountAmount: number; + itemDiscountAmount: number; total: number; } @@ -56,23 +57,27 @@ const normalizeItemPositions = (items: ProformaItemUpdateForm[]): ProformaItemUp }; const calculateItemAmounts = ( - item?: Pick + item?: Pick ): ProformaItemAmounts => { if (!item) { return { subtotal: 0, - discountAmount: 0, + itemDiscountAmount: 0, total: 0, }; } - const subtotal = roundCurrency(item.quantity * item.unitAmount); - const discountAmount = roundCurrency(subtotal * (item.discountPercentage / 100)); - const total = roundCurrency(subtotal - discountAmount); + const quantity = NumberHelper.toSafeNumber(item.quantity); + const unitAmount = NumberHelper.toSafeNumber(item.unitAmount); + const itemDiscountPercentage = NumberHelper.toSafeNumber(item.itemDiscountPercentage); + + const subtotal = roundCurrency(quantity * unitAmount); + const itemDiscountAmount = roundCurrency(subtotal * (itemDiscountPercentage / 100)); + const total = roundCurrency(subtotal - itemDiscountAmount); return { subtotal, - discountAmount, + itemDiscountAmount, total, }; }; @@ -84,7 +89,7 @@ const calculateItemsTotals = (items: ProformaItemUpdateForm[]): ProformaItemsTot return { subtotal: roundCurrency(acc.subtotal + amounts.subtotal), - discountAmount: roundCurrency(acc.discountAmount + amounts.discountAmount), + discountAmount: roundCurrency(acc.discountAmount + amounts.itemDiscountAmount), total: roundCurrency(acc.total + amounts.total), }; }, diff --git a/modules/customer-invoices/src/web/proformas/update/entities/index.ts b/modules/customer-invoices/src/web/proformas/update/entities/index.ts index 19bad70d..e14ff55c 100644 --- a/modules/customer-invoices/src/web/proformas/update/entities/index.ts +++ b/modules/customer-invoices/src/web/proformas/update/entities/index.ts @@ -1,5 +1,6 @@ export * from "./proforma-item-update-form.entity"; +export * from "./proforma-item-update-form.schema"; +export * from "./proforma-item-update-patch.entity"; export * from "./proforma-update-form.entity"; export * from "./proforma-update-form.schema"; -export * from "./proforma-update-form-default.entity"; export * from "./proforma-update-patch.entity"; diff --git a/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.entity.ts b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.entity.ts index 5bd9406e..eb1fb54b 100644 --- a/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.entity.ts +++ b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.entity.ts @@ -2,7 +2,7 @@ export interface ProformaItemUpdateForm { id: string; position: number; description: string; - quantity: number; - unitAmount: number; - discountPercentage: number; + quantity: number | null; + unitAmount: number | null; + itemDiscountPercentage: number | null; } diff --git a/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.schema.ts b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.schema.ts index 1a07d100..63255999 100644 --- a/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.schema.ts +++ b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-form.schema.ts @@ -17,10 +17,11 @@ import { z } from "zod/v4"; export const ProformaItemUpdateFormSchema = z.object({ id: z.uuid(), position: z.number().int().nonnegative(), + description: z.string().trim(), - quantity: z.number().positive(), - unitAmount: z.number().nonnegative(), - discountPercentage: z.number().min(0).max(100), + quantity: z.number().positive().nullable(), + unitAmount: z.number().nonnegative().nullable(), + itemDiscountPercentage: z.number().min(0).max(100).nullable(), }); -export type ProformaItemUpdateForm = z.infer; +export type ProformaItemUpdateFormSchemaType = z.infer; diff --git a/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-patch.entity.ts b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-patch.entity.ts new file mode 100644 index 00000000..600b8175 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/update/entities/proforma-item-update-patch.entity.ts @@ -0,0 +1,8 @@ +export interface ProformaItemUpdatePatch { + id: string; + position: number; + description: string; + quantity: number | null; + unitAmount: number | null; + itemDiscountPercentage: number | null; +} diff --git a/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form-default.entity.ts b/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form-default.entity.ts deleted file mode 100644 index a53581dd..00000000 --- a/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form-default.entity.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ProformaUpdateForm } from "."; - -export const defaultProformaUpdateForm: ProformaUpdateForm = { - series: "", - - invoiceDate: "", - operationDate: "", - - customerId: "", - - description: "", - reference: "", - notes: "", - - languageCode: "es", - currencyCode: "EUR", - - paymentMethod: "", - - globalDiscountPercentage: 0, - - items: [], -}; diff --git a/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form.entity.ts b/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form.entity.ts index f2d28221..857bc6df 100644 --- a/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form.entity.ts +++ b/modules/customer-invoices/src/web/proformas/update/entities/proforma-update-form.entity.ts @@ -13,7 +13,7 @@ * - sin detalles impuestos por el widget */ -import type { ProformaItemUpdateForm } from "./proforma-item-update-form.schema"; +import type { ProformaItemUpdateForm } from "./proforma-item-update-form.entity"; export interface ProformaUpdateForm { series: string; diff --git a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-editor-form.tsx b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-editor-form.tsx index 31ce0fd8..c3e4181f 100644 --- a/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-editor-form.tsx +++ b/modules/customer-invoices/src/web/proformas/update/ui/editors/proforma-update-editor-form.tsx @@ -42,7 +42,7 @@ export const ProformaUpdateEditorForm = ({ const { t } = useTranslation(); return ( -
+ - - -
@@ -70,7 +66,7 @@ export const ProformaUpdateItemRowEditor = ({
{t("form_fields.items.discount_amount.label", "Descuento")} - {amounts.discountAmount} + {amounts.itemDiscountAmount}
diff --git a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-item-update-default.ts b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-item-update-default.ts index 41d80167..3d0adafe 100644 --- a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-item-update-default.ts +++ b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-item-update-default.ts @@ -7,8 +7,8 @@ export const buildProformaItemUpdateDefault = (position: number): ProformaItemUp id: UniqueID.generateNewID().toString(), position, description: "", - quantity: 1, - unitAmount: 0, - discountPercentage: 0, + quantity: null, + unitAmount: null, + itemDiscountPercentage: null, }; }; diff --git a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-items-update-patch.ts b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-items-update-patch.ts new file mode 100644 index 00000000..34d799a0 --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-items-update-patch.ts @@ -0,0 +1,14 @@ +import type { ProformaItemUpdateForm, ProformaItemUpdatePatch } from "../entities"; + +export const buildProformaItemsUpdatePatch = ( + items: ProformaItemUpdateForm[] +): ProformaItemUpdatePatch[] => { + return items.map((item, index) => ({ + id: item.id, + position: index, + description: item.description.trim(), + quantity: item.quantity, + unitAmount: item.unitAmount, + itemDiscountPercentage: item.itemDiscountPercentage, + })); +}; diff --git a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-default.ts b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-default.ts new file mode 100644 index 00000000..13d34fef --- /dev/null +++ b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-default.ts @@ -0,0 +1,25 @@ +import type { ProformaUpdateForm } from "../entities"; + +export const buildProformaUpdateDefault = (): ProformaUpdateForm => { + return { + series: "", + + invoiceDate: "", + operationDate: "", + + customerId: "", + + description: "", + reference: "", + notes: "", + + languageCode: "es", + currencyCode: "EUR", + + paymentMethod: "", + + globalDiscountPercentage: 0, + + items: [], + }; +}; diff --git a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-patch.ts b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-patch.ts index 8496694a..0ea7a82c 100644 --- a/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-patch.ts +++ b/modules/customer-invoices/src/web/proformas/update/utils/build-proforma-update-patch.ts @@ -3,6 +3,8 @@ import type { FieldNamesMarkedBoolean } from "react-hook-form"; import type { ProformaUpdateForm, ProformaUpdatePatch } from "../entities"; +import { buildProformaItemsUpdatePatch } from "./build-proforma-items-update-patch"; + export const buildProformaUpdatePatch = ( formData: ProformaUpdateForm, dirtyFields: FieldNamesMarkedBoolean @@ -11,5 +13,10 @@ export const buildProformaUpdatePatch = ( return {}; } - return pickFormDirtyValues(formData, dirtyFields) as ProformaUpdatePatch; + const itemsPatch = buildProformaItemsUpdatePatch(formData.items); + + return { + ...pickFormDirtyValues(formData, dirtyFields), + items: itemsPatch, + } as ProformaUpdatePatch; }; diff --git a/modules/customer-invoices/src/web/proformas/update/utils/index.ts b/modules/customer-invoices/src/web/proformas/update/utils/index.ts index 5bfdadc2..155a3165 100644 --- a/modules/customer-invoices/src/web/proformas/update/utils/index.ts +++ b/modules/customer-invoices/src/web/proformas/update/utils/index.ts @@ -1,4 +1,5 @@ export * from "./build-proforma-item-update-default"; +export * from "./build-proforma-update-default"; export * from "./build-proforma-update-patch"; export * from "./build-update-proforma-by-id-params"; export * from "./focus-first-proforma-update-error"; diff --git a/modules/customers/src/web/update/ui/editor/customer-edit-form.tsx b/modules/customers/src/web/update/ui/editor/customer-edit-form.tsx index b8b854bf..cc2c6a2c 100644 --- a/modules/customers/src/web/update/ui/editor/customer-edit-form.tsx +++ b/modules/customers/src/web/update/ui/editor/customer-edit-form.tsx @@ -17,7 +17,7 @@ export const CustomerUpdateEditorForm = ({ className, }: CustomerUpdateEditorFormProps) => { return ( - +
diff --git a/packages/rdx-ui/src/components/form/decimal-field/decimal-field.tsx b/packages/rdx-ui/src/components/form/decimal-field/decimal-field.tsx new file mode 100644 index 00000000..3805533c --- /dev/null +++ b/packages/rdx-ui/src/components/form/decimal-field/decimal-field.tsx @@ -0,0 +1,180 @@ +import { + Field, + FieldDescription, + FieldError, + InputGroup, + InputGroupAddon, + InputGroupInput, +} from "@repo/shadcn-ui/components"; +import { cn } from "@repo/shadcn-ui/lib/utils"; +import * as React from "react"; +import { type FieldPath, type FieldValues, useController, useFormContext } from "react-hook-form"; + +import { FormFieldLabel } from "../form-field-label.tsx"; + +import type { DecimalFieldBaseProps } from "./decimal-field.types.ts"; +import { + DECIMAL_INPUT_PATTERN, + clampNumber, + formatDecimalValue, + parseDecimalOrNull, + trimToScale, +} from "./decimal-field.utils.ts"; + +type DecimalFieldProps = DecimalFieldBaseProps & { + name: FieldPath; +}; + +export const DecimalField = ({ + name, + + label, + description, + + required = false, + readOnly = false, + + orientation = "vertical", + + className, + inputClassName, + + leftIcon, + rightIcon, + leftAddon, + rightAddon, + + scale = 4, + min, + max, + + ...inputRest +}: DecimalFieldProps) => { + const { control, formState, getFieldState } = useFormContext(); + + const { field } = useController({ + name, + control, + defaultValue: null as any, + }); + + const inputId = React.useId(); + const disabled = formState.isSubmitting || inputRest.disabled; + const fieldError = getFieldState(name, formState).error; + const [inputValue, setInputValue] = React.useState(() => + formatDecimalValue(field.value as number | null | undefined, scale) + ); + + React.useEffect(() => { + const nextFormattedValue = formatDecimalValue(field.value as number | null | undefined, scale); + + setInputValue((currentValue) => + currentValue === nextFormattedValue ? currentValue : nextFormattedValue + ); + }, [field.value, scale]); + + const handleChange = (event: React.ChangeEvent) => { + const rawValue = event.target.value; + + if (rawValue === "") { + setInputValue(""); + field.onChange(null); + return; + } + + if (!DECIMAL_INPUT_PATTERN.test(rawValue)) { + return; + } + + const trimmedValue = trimToScale(rawValue, scale); + setInputValue(trimmedValue); + + const parsedValue = parseDecimalOrNull(trimmedValue); + + if (parsedValue === null) { + field.onChange(null); + return; + } + + field.onChange(clampNumber(parsedValue, min, max)); + }; + + const handleBlur = (event: React.FocusEvent) => { + field.onBlur(); + + const parsedValue = parseDecimalOrNull(event.target.value); + + if (parsedValue === null) { + setInputValue(""); + field.onChange(null); + return; + } + + const clampedValue = clampNumber(parsedValue, min, max); + const formattedValue = formatDecimalValue(clampedValue, scale); + + setInputValue(formattedValue); + field.onChange(clampedValue); + }; + + const renderedLeftAddon = leftAddon ?? leftIcon; + const renderedRightAddon = rightAddon ?? rightIcon; + + return ( + + {label ? ( + + {label} + + ) : null} + + <> + + {renderedLeftAddon ? ( + + ) : null} + + + + {renderedRightAddon ? ( + + ) : null} + + + {description ? ( + {description} + ) : ( +