MoneyInput
WhereUIช่องกรอกจำนวนเงินบาท คั่นหลักพันและทศนิยม 2 ตำแหน่งอัตโนมัติ ค่าที่รับ/ส่งเป็นจำนวนเต็มหน่วยสตางค์เพื่อเลี่ยงปัญหาจุดทศนิยม
ค่าที่ได้ (สตางค์): 2,500,000
ติดตั้ง
Terminal
pnpm dlx shadcn@latest add @whereui/money-inputต้องผูก registry และติดตั้ง @whereui/theme นำหน้าเสมอเมื่อติดตั้งครั้งแรก
การใช้งาน
import { MoneyInput } from "@/components/ui/money-input"const [satang, setSatang] = React.useState<number | null>(null)<MoneyInput value={satang} onChange={setSatang} />ตัวอย่างเพิ่มเติม
สถานะปิดใช้งาน
งบประมาณที่ขออนุมัติ
ปิดใช้งาน (สำหรับฟิลด์ที่คำนวณให้แล้ว)
Props
| prop | type | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|---|
| value | number | null | — | จำนวนเงินเป็นจำนวนเต็มหน่วยสตางค์ เช่น 123450 = 1,234.50 บาท (null = ว่าง) |
| onChange | (satang: number | null) => void | — | ส่งค่ากลับเป็นสตางค์จำนวนเต็ม หรือ null เมื่อว่าง |
| placeholder | string | "0.00" | ข้อความเมื่อว่าง |
| disabled | boolean | — | ปิดการใช้งาน |
ข้อควรรู้
- ค่าที่รับ/ส่งเป็นจำนวนเต็มหน่วยสตางค์เสมอ — ห้ามเก็บบาทแบบทศนิยมโดยตรงในระบบบัญชี
- พิมพ์เลขแล้วคั่นหลักพันจะปรากฏให้เองเมื่อเสร็จสรรพ (ตอน blur)
ซอร์สโค้ด
components/ui/money-input.tsx
"use client"import * as React from "react"import { NumberField } from "@base-ui/react/number-field"import { cn } from "cn"/** สตางค์ -> บาท (สำหรับส่งเข้า NumberField) */function satangToBaht(satang: number) { return satang / 100}function MoneyInput({ value, onChange, disabled, placeholder = "0.00", className, ...props}: Omit<React.ComponentProps<"input">, "value" | "onChange" | "size" | "type"> & { /** จำนวนเงินเป็นจำนวนเต็มหน่วยสตางค์ เช่น 123450 = 1,234.50 บาท (null = ว่าง) */ value?: number | null onChange?: (satang: number | null) => void}) { return ( <NumberField.Root data-slot="money-input" value={value == null ? null : satangToBaht(value)} onValueChange={(v) => onChange?.(v == null ? null : Math.round(v * 100))} disabled={disabled} locale="th-TH" format={{ minimumFractionDigits: 2, maximumFractionDigits: 2 }} className={cn( "flex h-8 w-full min-w-0 items-center rounded-lg border border-input bg-transparent transition-colors outline-none focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/50 data-invalid:border-destructive data-invalid:ring-3 data-invalid:ring-destructive/20 disabled:cursor-not-allowed disabled:opacity-50 disabled:pointer-events-none md:text-sm dark:bg-input/30 dark:data-invalid:border-destructive/50 dark:data-invalid:ring-destructive/40", className )} > <NumberField.Input inputMode="decimal" placeholder={placeholder} className="w-full min-w-0 bg-transparent px-2.5 py-1 text-base tabular-nums outline-none placeholder:text-muted-foreground md:text-sm" {...props} /> <span aria-hidden="true" className="shrink-0 pr-2.5 text-sm text-muted-foreground select-none" > บาท </span> </NumberField.Root> )}export { MoneyInput }