d2aa9d8ae2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
"use client";
|
||
|
||
import {
|
||
InputGroup,
|
||
InputGroupAddon,
|
||
InputGroupInput,
|
||
InputGroupText,
|
||
} from "@/components/ui/input-group";
|
||
import { formatMoneyInput, parseMoney } from "@/shared/money";
|
||
|
||
/**
|
||
* Türkçe tutar girişi ("1.250,50"). Değer string olarak tutulur (zod sunucuda/istemcide ayrıştırır);
|
||
* alandan çıkınca geçerliyse Türkçe biçime getirilir.
|
||
*/
|
||
export function MoneyInput({
|
||
value,
|
||
onChange,
|
||
onBlur,
|
||
allowNegative = false,
|
||
...props
|
||
}: Omit<React.ComponentProps<typeof InputGroupInput>, "value" | "onChange" | "type"> & {
|
||
value: string;
|
||
onChange: (value: string) => void;
|
||
allowNegative?: boolean;
|
||
}) {
|
||
return (
|
||
<InputGroup>
|
||
<InputGroupInput
|
||
{...props}
|
||
type="text"
|
||
inputMode="decimal"
|
||
autoComplete="off"
|
||
className="text-right tabular-nums"
|
||
value={value}
|
||
onChange={(e) =>
|
||
onChange(e.target.value.replace(allowNegative ? /[^\d.,\s-−]/g : /[^\d.,\s]/g, ""))
|
||
}
|
||
onBlur={(e) => {
|
||
const minor = parseMoney(value);
|
||
if (minor !== null && value.trim() !== "") onChange(formatMoneyInput(minor));
|
||
onBlur?.(e);
|
||
}}
|
||
/>
|
||
<InputGroupAddon align="inline-end">
|
||
<InputGroupText>₺</InputGroupText>
|
||
</InputGroupAddon>
|
||
</InputGroup>
|
||
);
|
||
}
|