ar-design
Version:
AR Design is a (react | nextjs) ui library.
74 lines (73 loc) • 3.1 kB
JavaScript
"use client";
import React, { useEffect, useMemo, useRef, useState } from "react";
import Input from "..";
import { NUMBER } from "../../../../libs/infrastructure/shared";
const FormattedDecimal = ({ variant, color, name, value, onChange, locale = "tr-TR", digits, placeholder, validation, disabled, }) => {
const _input = useRef(null);
const [_value, setValue] = useState("");
// methods
const getSeparators = (locale) => {
const parts = new Intl.NumberFormat(locale).formatToParts(1000.1);
const group = parts.find((p) => p.type === "group")?.value ?? ",";
const decimal = parts.find((p) => p.type === "decimal")?.value ?? ".";
return { group, decimal };
};
const getFormatter = useMemo(() => NUMBER.Decimal(locale, digits), [locale, digits]);
const handleClick = () => {
const input = _input.current;
if (!input)
return;
const caret = input.selectionStart ?? 0;
input.setSelectionRange(caret, caret + 1);
};
const handleKeyUp = (event) => {
const input = _input.current;
if (!input)
return;
const caret = input.selectionStart ?? 0;
if (event.code === "ArrowRight") {
input.setSelectionRange(caret, caret + 1);
}
else if (event.code === "ArrowLeft" && caret > 0) {
input.setSelectionRange(caret - 1, caret);
}
else if (["ArrowUp", "ArrowDown"].includes(event.code)) {
input.setSelectionRange(caret, caret + 1);
}
};
const handleChange = (event) => {
let { value } = event.target;
const { group, decimal } = getSeparators(locale);
// Locale’a göre izin verilen karakterleri temizle.
const regex = new RegExp(`[^0-9\\${group}\\${decimal}]`, "g");
value = value.replace(regex, "");
// Normalize et (decimal her zaman "." olacak şekilde)
let normalized = value.replace(new RegExp(`\\${group}`, "g"), "").replace(decimal, ".");
const parsed = parseFloat(normalized);
const numericValue = isNaN(parsed) ? 0 : parsed;
const formatted = value === "" ? "" : getFormatter.format(numericValue);
setValue(formatted);
onChange?.({
...event,
target: {
...event.target,
name,
value: normalized,
},
});
};
// useEffects
useEffect(() => {
if (value === undefined || value === null || value === "") {
setValue("");
return;
}
setValue(getFormatter.format(Number(value)));
}, [value, getFormatter]);
return (React.createElement(Input, { ref: _input, name: name, variant: variant, color: color, value: _value, type: "text", inputMode: "decimal", onChange: (event) => {
if (disabled)
return;
handleChange(event);
}, onClick: handleClick, onKeyUp: handleKeyUp, placeholder: placeholder, validation: validation, disabled: disabled }));
};
export default FormattedDecimal;