@giro-ds/react 12.6.2 → 12.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +92 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +94 -52
- package/dist/index.esm.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -497,6 +497,8 @@ interface DatePickerProps extends ScalableProps {
|
|
|
497
497
|
minDate?: Date;
|
|
498
498
|
/** Data máxima selecionável */
|
|
499
499
|
maxDate?: Date;
|
|
500
|
+
/** Define se o calendário pode ser aberto ao clicar/focar no campo */
|
|
501
|
+
showCalendar?: boolean;
|
|
500
502
|
/** ID para testes automatizados */
|
|
501
503
|
'data-testid'?: string;
|
|
502
504
|
}
|
|
@@ -1001,6 +1003,8 @@ interface QuantityProps extends ScalableProps, Omit<React$1.HTMLAttributes<HTMLD
|
|
|
1001
1003
|
size?: Size;
|
|
1002
1004
|
/** Número de casas decimais permitidas */
|
|
1003
1005
|
decimalPlaces?: number;
|
|
1006
|
+
/** Caractere usado como separador decimal. Padrão: ',' */
|
|
1007
|
+
decimalSeparator?: ',' | '.';
|
|
1004
1008
|
/** Incremento/decremento ao clicar nos botões */
|
|
1005
1009
|
valueIncrement?: number;
|
|
1006
1010
|
/**
|
package/dist/index.esm.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
|
|
5
5
|
import React__default, { useId, version, forwardRef as forwardRef$1, useMemo, createContext, useState, useContext, useRef, useCallback, useEffect, useLayoutEffect, createElement, memo, useReducer } from 'react';
|
|
6
6
|
import { SpinnerIos16Regular, ChevronUp16Regular, ChevronLeft16Regular, ChevronRight16Regular, ChevronDown16Regular, Dismiss24Regular, Spacebar20Regular, ArrowImport20Regular, Emoji20Regular, ChevronDown20Regular, KeyboardShiftUppercase20Regular, KeyboardShift20Filled, KeyboardShift20Regular, Backspace20Regular, Info12Regular, Dismiss16Regular, Calendar16Regular, DocumentAdd24Regular, Warning24Regular, Document24Regular, FilterRegular, Search16Regular, ChevronDownRegular, ChevronRight16Filled, Subtract16Regular, Add16Regular, SearchInfo20Regular, ArrowSortUp16Regular, ArrowSortDown16Regular, ArrowSort16Regular, Info20Filled, CheckmarkCircle20Filled, Warning20Filled, Dismiss16Filled } from '@fluentui/react-icons';
|
|
7
7
|
import { DayPicker } from 'react-day-picker';
|
|
8
|
-
import { format, addDays, addMonths, addWeeks, addYears, differenceInCalendarDays, differenceInCalendarMonths, eachMonthOfInterval, eachYearOfInterval, endOfISOWeek, endOfMonth, endOfWeek, endOfYear, getISOWeek, getMonth, getYear, getWeek, isAfter, isBefore, isDate, isSameDay, isSameMonth, isSameYear, max, min, setMonth, setYear, startOfDay, startOfISOWeek, startOfMonth, startOfWeek, startOfYear } from 'date-fns';
|
|
8
|
+
import { format, addDays, addMonths, addWeeks, addYears, differenceInCalendarDays, differenceInCalendarMonths, eachMonthOfInterval, eachYearOfInterval, endOfISOWeek, endOfMonth, endOfWeek, endOfYear, getISOWeek, getMonth, getYear, getWeek, isAfter, isBefore, isDate, isSameDay, isSameMonth, isSameYear, max, min, setMonth, setYear, startOfDay as startOfDay$1, startOfISOWeek, startOfMonth, startOfWeek, startOfYear } from 'date-fns';
|
|
9
9
|
import { createPortal } from 'react-dom';
|
|
10
10
|
import Keyboard from 'react-simple-keyboard';
|
|
11
11
|
import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
@@ -2513,7 +2513,7 @@ class DateLib {
|
|
|
2513
2513
|
this.startOfDay = (date) => {
|
|
2514
2514
|
return this.overrides?.startOfDay
|
|
2515
2515
|
? this.overrides.startOfDay(date)
|
|
2516
|
-
: startOfDay(date);
|
|
2516
|
+
: startOfDay$1(date);
|
|
2517
2517
|
};
|
|
2518
2518
|
/**
|
|
2519
2519
|
* Returns the start of the ISO week for the given date.
|
|
@@ -3908,8 +3908,21 @@ function validatePartialDate(value, locale = 'pt-br') {
|
|
|
3908
3908
|
}
|
|
3909
3909
|
return 'incomplete';
|
|
3910
3910
|
}
|
|
3911
|
+
function startOfDay(date) {
|
|
3912
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
3913
|
+
}
|
|
3914
|
+
function isDateInRange(date, minDate, maxDate) {
|
|
3915
|
+
const day = startOfDay(date);
|
|
3916
|
+
if (minDate && day < startOfDay(minDate)) {
|
|
3917
|
+
return false;
|
|
3918
|
+
}
|
|
3919
|
+
if (maxDate && day > startOfDay(maxDate)) {
|
|
3920
|
+
return false;
|
|
3921
|
+
}
|
|
3922
|
+
return true;
|
|
3923
|
+
}
|
|
3911
3924
|
|
|
3912
|
-
const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign = 'start', helperText, required = false, label, value, defaultValue, onChange, disabled = false, error: externalError, minDate, maxDate, 'data-testid': testId, scale = 1, id, className, style, ...rest }) => {
|
|
3925
|
+
const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign = 'start', helperText, required = false, label, value, defaultValue, onChange, disabled = false, error: externalError, minDate, maxDate, showCalendar = true, 'data-testid': testId, scale = 1, id, className, style, ...rest }) => {
|
|
3913
3926
|
const fieldId = useId();
|
|
3914
3927
|
const calendarId = `${fieldId}-calendar`;
|
|
3915
3928
|
const containerStyle = { '--giro-scale': scale };
|
|
@@ -3918,31 +3931,40 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
|
|
|
3918
3931
|
const [tempInputValue, setTempInputValue] = useState('');
|
|
3919
3932
|
const [isEditing, setIsEditing] = useState(false);
|
|
3920
3933
|
const [internalError, setInternalError] = useState('');
|
|
3921
|
-
const [
|
|
3934
|
+
const [isCalendarOpen, setIsCalendarOpen] = useState(false);
|
|
3922
3935
|
const [currentDate, setCurrentDate] = useState(new Date());
|
|
3923
3936
|
const wrapperRef = useRef(null);
|
|
3924
3937
|
const currentSelectedDate = isControlled ? value : internalDate;
|
|
3925
3938
|
const hasValidationError = !!(externalError || internalError);
|
|
3926
3939
|
const displayValue = isEditing ? tempInputValue : (currentSelectedDate ? formatDate(currentSelectedDate, locale) : '');
|
|
3927
|
-
const
|
|
3928
|
-
|
|
3929
|
-
|
|
3940
|
+
const invalidDateMessage = locale === 'en-us' ? 'Invalid date' : 'Data inválida';
|
|
3941
|
+
const outOfRangeMessage = locale === 'en-us' ? 'Date out of allowed range' : 'Data fora do intervalo permitido';
|
|
3942
|
+
const internalErrorText = internalError === 'invalid'
|
|
3943
|
+
? invalidDateMessage
|
|
3944
|
+
: internalError === 'range'
|
|
3945
|
+
? outOfRangeMessage
|
|
3946
|
+
: '';
|
|
3947
|
+
const combinedHelperText = internalErrorText
|
|
3948
|
+
? internalErrorText
|
|
3949
|
+
: externalError && helperText
|
|
3950
|
+
? `${helperText} • ${externalError}`
|
|
3951
|
+
: externalError || helperText || '';
|
|
3930
3952
|
useEffect(() => {
|
|
3931
3953
|
function handleClickOutside(event) {
|
|
3932
3954
|
const target = event.target;
|
|
3933
3955
|
const isInsideWrapper = wrapperRef.current?.contains(target);
|
|
3934
3956
|
const isInsideCalendar = !!target.closest?.('[data-radix-popper-content-wrapper]');
|
|
3935
3957
|
if (!isInsideWrapper && !isInsideCalendar) {
|
|
3936
|
-
|
|
3958
|
+
setIsCalendarOpen(false);
|
|
3937
3959
|
}
|
|
3938
3960
|
}
|
|
3939
|
-
if (
|
|
3961
|
+
if (isCalendarOpen) {
|
|
3940
3962
|
document.addEventListener('mousedown', handleClickOutside);
|
|
3941
3963
|
}
|
|
3942
3964
|
return () => {
|
|
3943
3965
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
3944
3966
|
};
|
|
3945
|
-
}, [
|
|
3967
|
+
}, [isCalendarOpen]);
|
|
3946
3968
|
const handleDateChange = useCallback((newDate) => {
|
|
3947
3969
|
if (!isControlled) {
|
|
3948
3970
|
setInternalDate(newDate);
|
|
@@ -3956,36 +3978,43 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
|
|
|
3956
3978
|
}
|
|
3957
3979
|
}, [isControlled, onChange]);
|
|
3958
3980
|
const handleIconClick = () => {
|
|
3959
|
-
|
|
3981
|
+
if (!showCalendar)
|
|
3982
|
+
return;
|
|
3983
|
+
setIsCalendarOpen((prev) => !prev);
|
|
3960
3984
|
};
|
|
3961
3985
|
const handleKeyDown = (event) => {
|
|
3962
3986
|
const { key } = event;
|
|
3963
3987
|
if (key === 'Enter') {
|
|
3964
|
-
if (
|
|
3988
|
+
if (isCalendarOpen) {
|
|
3965
3989
|
if (currentSelectedDate) {
|
|
3966
|
-
|
|
3990
|
+
setIsCalendarOpen(false);
|
|
3967
3991
|
event.preventDefault();
|
|
3968
3992
|
return;
|
|
3969
3993
|
}
|
|
3970
3994
|
if (tempInputValue.length === 10 && isValidDateFormat(tempInputValue, locale)) {
|
|
3971
3995
|
const parsedDate = parseDate(tempInputValue, locale);
|
|
3972
3996
|
if (parsedDate && !isNaN(parsedDate.getTime())) {
|
|
3997
|
+
if (!isDateInRange(parsedDate, minDate, maxDate)) {
|
|
3998
|
+
setInternalError('range');
|
|
3999
|
+
event.preventDefault();
|
|
4000
|
+
return;
|
|
4001
|
+
}
|
|
3973
4002
|
handleDateChange(parsedDate);
|
|
3974
|
-
|
|
4003
|
+
setIsCalendarOpen(false);
|
|
3975
4004
|
event.preventDefault();
|
|
3976
4005
|
return;
|
|
3977
4006
|
}
|
|
3978
4007
|
}
|
|
3979
4008
|
}
|
|
3980
|
-
else {
|
|
3981
|
-
|
|
4009
|
+
else if (showCalendar) {
|
|
4010
|
+
setIsCalendarOpen(true);
|
|
3982
4011
|
event.preventDefault();
|
|
3983
4012
|
return;
|
|
3984
4013
|
}
|
|
3985
4014
|
}
|
|
3986
4015
|
if (key === 'Escape') {
|
|
3987
|
-
if (
|
|
3988
|
-
|
|
4016
|
+
if (isCalendarOpen) {
|
|
4017
|
+
setIsCalendarOpen(false);
|
|
3989
4018
|
event.preventDefault();
|
|
3990
4019
|
return;
|
|
3991
4020
|
}
|
|
@@ -4001,12 +4030,12 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
|
|
|
4001
4030
|
}
|
|
4002
4031
|
};
|
|
4003
4032
|
const handleDaySelect = (newSelectedDate) => {
|
|
4004
|
-
|
|
4033
|
+
setIsCalendarOpen(false);
|
|
4005
4034
|
handleDateChange(newSelectedDate);
|
|
4006
4035
|
};
|
|
4007
4036
|
const handleFocus = () => {
|
|
4008
|
-
if (!disabled) {
|
|
4009
|
-
|
|
4037
|
+
if (!disabled && showCalendar) {
|
|
4038
|
+
setIsCalendarOpen(true);
|
|
4010
4039
|
}
|
|
4011
4040
|
};
|
|
4012
4041
|
const handleTextFieldChange = (value) => {
|
|
@@ -4033,15 +4062,25 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
|
|
|
4033
4062
|
if (maskedValue.length === 10) {
|
|
4034
4063
|
const parsedDate = parseDate(maskedValue, locale);
|
|
4035
4064
|
if (parsedDate) {
|
|
4065
|
+
if (!isDateInRange(parsedDate, minDate, maxDate)) {
|
|
4066
|
+
setInternalError('range');
|
|
4067
|
+
if (!isControlled)
|
|
4068
|
+
setInternalDate(null);
|
|
4069
|
+
onChange?.(null);
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4036
4072
|
handleDateChange(parsedDate);
|
|
4037
4073
|
setCurrentDate(parsedDate);
|
|
4038
4074
|
}
|
|
4039
4075
|
}
|
|
4040
4076
|
}
|
|
4041
4077
|
};
|
|
4042
|
-
return (jsx("div", { ref: wrapperRef, id: id, className: clsx(styles$h.datePicker, className), style: { ...containerStyle, ...style }, ...rest, children: jsx(Popover, { open: showCalendar
|
|
4078
|
+
return (jsx("div", { ref: wrapperRef, id: id, className: clsx(styles$h.datePicker, className), style: { ...containerStyle, ...style }, ...rest, children: jsx(Popover, { open: showCalendar && isCalendarOpen, onOpenChange: (open) => {
|
|
4079
|
+
if (showCalendar)
|
|
4080
|
+
setIsCalendarOpen(open);
|
|
4081
|
+
}, asAnchor: true, trigger: jsx(TextField$1, { className: styles$h.textfieldContainer, type: "tel", icon: jsx(Calendar16Regular, { onClick: !disabled ? handleIconClick : undefined, className: clsx(styles$h.datePickerIcon, disabled && styles$h.datePickerIconDisabled) }), onChange: (e) => {
|
|
4043
4082
|
handleTextFieldChange(String(e));
|
|
4044
|
-
}, onKeyDown: handleKeyDown, onFocus: handleFocus, autoComplete: "off", value: displayValue, helperText: !
|
|
4083
|
+
}, onKeyDown: handleKeyDown, onFocus: handleFocus, autoComplete: "off", value: displayValue, helperText: !hasValidationError ? (helperText || undefined) : undefined, errorMessage: hasValidationError ? combinedHelperText : undefined, error: hasValidationError ? true : undefined, maxLength: 10, required: required, label: label, disabled: disabled, scale: scale, id: fieldId, "data-testid": testId, placeholder: locale === 'en-us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY', "aria-label": "Open calendar", "aria-expanded": showCalendar && isCalendarOpen, "aria-controls": calendarId, "aria-invalid": hasValidationError, "aria-describedby": hasValidationError ? undefined : (helperText ? `${fieldId}-help` : undefined) }), content: jsx(Calendar, { selected: currentSelectedDate, currentDate: currentDate, onDateChange: setCurrentDate, onDaySelect: handleDaySelect, locale: locale, format: locale === 'en-us' ? 'mm/dd/yyyy' : 'dd/mm/yyyy', minDate: minDate, maxDate: maxDate, scale: scale, id: calendarId, onClear: () => {
|
|
4045
4084
|
handleDateChange(null);
|
|
4046
4085
|
setCurrentDate(new Date());
|
|
4047
4086
|
} }), side: calendarSide, align: calendarAlign, sideOffset: 8 }) }));
|
|
@@ -4967,11 +5006,12 @@ const Modal = ({ isOpen = false, onClose, title, children, headerContent, closeO
|
|
|
4967
5006
|
|
|
4968
5007
|
var styles$8 = {"quantity":"Quantity-module__quantity___-vndR","quantityInput":"Quantity-module__quantityInput___xZG-v","disabled":"Quantity-module__disabled___X6p5l"};
|
|
4969
5008
|
|
|
4970
|
-
const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, decimalPlaces = 2, size = 'lg', id, valueIncrement = 1, scale = 1, className, style, inputSize, minValue = 0, maxValue = 9999, decrementAriaLabel = 'Decrease quantity', incrementAriaLabel = 'Increase quantity', inputAriaLabel = 'Quantity', ...rest }) => {
|
|
5009
|
+
const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, decimalPlaces = 2, decimalSeparator = ',', size = 'lg', id, valueIncrement = 1, scale = 1, className, style, inputSize, minValue = 0, maxValue = 9999, decrementAriaLabel = 'Decrease quantity', incrementAriaLabel = 'Increase quantity', inputAriaLabel = 'Quantity', ...rest }) => {
|
|
4971
5010
|
const initialValue = Math.min(Math.max(value, minValue), maxValue);
|
|
4972
5011
|
const [internalValue, setInternalValue] = useState(initialValue);
|
|
4973
|
-
const [inputValue, setInputValue] = useState(decimal ? initialValue.toFixed(decimalPlaces) : String(initialValue));
|
|
5012
|
+
const [inputValue, setInputValue] = useState(decimal ? initialValue.toFixed(decimalPlaces).replace('.', decimalSeparator) : String(initialValue));
|
|
4974
5013
|
const inputRef = useRef(null);
|
|
5014
|
+
const formatDecimalValue = useCallback((num) => num.toFixed(decimalPlaces).replace('.', decimalSeparator), [decimalPlaces, decimalSeparator]);
|
|
4975
5015
|
const stepValue = valueIncrement !== undefined ? valueIncrement : decimal ? Math.pow(10, -decimalPlaces) : 1;
|
|
4976
5016
|
const isMinValue = useMemo(() => internalValue <= minValue, [internalValue, minValue]);
|
|
4977
5017
|
const isMaxValue = useMemo(() => internalValue >= maxValue, [internalValue, maxValue]);
|
|
@@ -4989,32 +5029,34 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
4989
5029
|
useEffect(() => {
|
|
4990
5030
|
const clamped = Math.min(Math.max(value, minValue), maxValue);
|
|
4991
5031
|
setInternalValue(clamped);
|
|
4992
|
-
setInputValue(decimal ? clamped
|
|
4993
|
-
}, [value, minValue, maxValue, decimal,
|
|
5032
|
+
setInputValue(decimal ? formatDecimalValue(clamped) : String(clamped));
|
|
5033
|
+
}, [value, minValue, maxValue, decimal, formatDecimalValue]);
|
|
4994
5034
|
const increment = useCallback(() => {
|
|
4995
5035
|
if (disabled)
|
|
4996
5036
|
return;
|
|
4997
5037
|
const newValue = Math.min(maxValue, internalValue + stepValue);
|
|
4998
5038
|
setInternalValue(newValue);
|
|
4999
|
-
setInputValue(decimal ? newValue
|
|
5039
|
+
setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
|
|
5000
5040
|
onChange?.(newValue);
|
|
5001
|
-
}, [disabled, internalValue, stepValue, decimal,
|
|
5041
|
+
}, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, maxValue]);
|
|
5002
5042
|
const decrement = useCallback(() => {
|
|
5003
5043
|
if (disabled)
|
|
5004
5044
|
return;
|
|
5005
5045
|
const newValue = Math.max(minValue, internalValue - stepValue);
|
|
5006
5046
|
setInternalValue(newValue);
|
|
5007
|
-
setInputValue(decimal ? newValue
|
|
5047
|
+
setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
|
|
5008
5048
|
onChange?.(newValue);
|
|
5009
|
-
}, [disabled, internalValue, stepValue, decimal,
|
|
5049
|
+
}, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, minValue]);
|
|
5010
5050
|
const filterInput = useCallback((inputValue) => {
|
|
5011
5051
|
if (decimal) {
|
|
5012
|
-
|
|
5013
|
-
const
|
|
5052
|
+
const escapedSeparator = decimalSeparator.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
5053
|
+
const allowedCharsRegex = new RegExp(`[^\\d${escapedSeparator}]`, 'g');
|
|
5054
|
+
let filtered = inputValue.replace(allowedCharsRegex, '');
|
|
5055
|
+
const parts = filtered.split(decimalSeparator);
|
|
5014
5056
|
if (parts.length > 2) {
|
|
5015
|
-
filtered = parts[0] +
|
|
5057
|
+
filtered = parts[0] + decimalSeparator + parts.slice(1).join('');
|
|
5016
5058
|
}
|
|
5017
|
-
if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith(
|
|
5059
|
+
if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith(`0${decimalSeparator}`)) {
|
|
5018
5060
|
filtered = filtered.replace(/^0+/, '');
|
|
5019
5061
|
}
|
|
5020
5062
|
return filtered;
|
|
@@ -5026,22 +5068,22 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
5026
5068
|
}
|
|
5027
5069
|
return filtered || '0'; // Se ficar vazio, retorna '0'
|
|
5028
5070
|
}
|
|
5029
|
-
}, [decimal]);
|
|
5071
|
+
}, [decimal, decimalSeparator]);
|
|
5030
5072
|
const handleInputChange = useCallback((event) => {
|
|
5031
5073
|
if (disabled)
|
|
5032
5074
|
return;
|
|
5033
5075
|
const rawValue = event.target.value;
|
|
5034
5076
|
const filteredValue = filterInput(rawValue);
|
|
5035
5077
|
setInputValue(filteredValue);
|
|
5036
|
-
if (filteredValue === '' || filteredValue ===
|
|
5078
|
+
if (filteredValue === '' || filteredValue === decimalSeparator) {
|
|
5037
5079
|
onChange?.(0);
|
|
5038
5080
|
return;
|
|
5039
5081
|
}
|
|
5040
5082
|
if (decimal) {
|
|
5041
|
-
if (filteredValue.endsWith(
|
|
5083
|
+
if (filteredValue.endsWith(decimalSeparator)) {
|
|
5042
5084
|
return;
|
|
5043
5085
|
}
|
|
5044
|
-
const parsedValue = parseFloat(filteredValue);
|
|
5086
|
+
const parsedValue = parseFloat(filteredValue.replace(decimalSeparator, '.'));
|
|
5045
5087
|
if (!isNaN(parsedValue)) {
|
|
5046
5088
|
onChange?.(parsedValue);
|
|
5047
5089
|
}
|
|
@@ -5053,36 +5095,36 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
5053
5095
|
onChange?.(validValue);
|
|
5054
5096
|
}
|
|
5055
5097
|
}
|
|
5056
|
-
}, [disabled, decimal, filterInput, onChange, minValue, maxValue]);
|
|
5098
|
+
}, [disabled, decimal, decimalSeparator, filterInput, onChange, minValue, maxValue]);
|
|
5057
5099
|
const handleBlur = useCallback(() => {
|
|
5058
5100
|
if (disabled)
|
|
5059
5101
|
return;
|
|
5060
5102
|
const currentValue = inputValue.trim();
|
|
5061
5103
|
if (decimal) {
|
|
5062
|
-
if (currentValue === '' || currentValue ===
|
|
5063
|
-
setInputValue(internalValue
|
|
5104
|
+
if (currentValue === '' || currentValue === decimalSeparator) {
|
|
5105
|
+
setInputValue(formatDecimalValue(internalValue));
|
|
5064
5106
|
return;
|
|
5065
5107
|
}
|
|
5066
|
-
if (currentValue.endsWith(
|
|
5067
|
-
const baseValue = parseFloat(currentValue.slice(0, -1));
|
|
5108
|
+
if (currentValue.endsWith(decimalSeparator)) {
|
|
5109
|
+
const baseValue = parseFloat(currentValue.slice(0, -1).replace(decimalSeparator, '.'));
|
|
5068
5110
|
if (!isNaN(baseValue)) {
|
|
5069
|
-
const formattedValue = baseValue
|
|
5111
|
+
const formattedValue = formatDecimalValue(baseValue);
|
|
5070
5112
|
setInputValue(formattedValue);
|
|
5071
5113
|
setInternalValue(baseValue);
|
|
5072
5114
|
onChange?.(baseValue);
|
|
5073
5115
|
}
|
|
5074
5116
|
return;
|
|
5075
5117
|
}
|
|
5076
|
-
const parsedValue = parseFloat(currentValue);
|
|
5118
|
+
const parsedValue = parseFloat(currentValue.replace(decimalSeparator, '.'));
|
|
5077
5119
|
if (!isNaN(parsedValue)) {
|
|
5078
5120
|
const normalizedValue = Math.min(Math.max(parsedValue, minValue), maxValue);
|
|
5079
|
-
const formattedValue = normalizedValue
|
|
5121
|
+
const formattedValue = formatDecimalValue(normalizedValue);
|
|
5080
5122
|
setInputValue(formattedValue);
|
|
5081
5123
|
setInternalValue(normalizedValue);
|
|
5082
5124
|
onChange?.(normalizedValue);
|
|
5083
5125
|
}
|
|
5084
5126
|
else {
|
|
5085
|
-
setInputValue(internalValue
|
|
5127
|
+
setInputValue(formatDecimalValue(internalValue));
|
|
5086
5128
|
}
|
|
5087
5129
|
}
|
|
5088
5130
|
else {
|
|
@@ -5101,7 +5143,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
5101
5143
|
onChange?.(normalizedValue);
|
|
5102
5144
|
}
|
|
5103
5145
|
}
|
|
5104
|
-
}, [disabled, decimal, inputValue,
|
|
5146
|
+
}, [disabled, decimal, decimalSeparator, inputValue, formatDecimalValue, internalValue, onChange, minValue, maxValue]);
|
|
5105
5147
|
const handleInputKeyDown = useCallback((e) => {
|
|
5106
5148
|
if (disabled)
|
|
5107
5149
|
return;
|
|
@@ -5123,14 +5165,14 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
5123
5165
|
case 'Escape':
|
|
5124
5166
|
e.preventDefault();
|
|
5125
5167
|
if (inputRef.current) {
|
|
5126
|
-
setInputValue(decimal ? internalValue
|
|
5168
|
+
setInputValue(decimal ? formatDecimalValue(internalValue) : String(internalValue));
|
|
5127
5169
|
inputRef.current.blur();
|
|
5128
5170
|
}
|
|
5129
5171
|
break;
|
|
5130
5172
|
case 'Home':
|
|
5131
5173
|
e.preventDefault();
|
|
5132
5174
|
setInternalValue(minValue);
|
|
5133
|
-
setInputValue(decimal ? minValue
|
|
5175
|
+
setInputValue(decimal ? formatDecimalValue(minValue) : String(minValue));
|
|
5134
5176
|
onChange?.(minValue);
|
|
5135
5177
|
break;
|
|
5136
5178
|
case 'End':
|
|
@@ -5142,7 +5184,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
|
|
|
5142
5184
|
}
|
|
5143
5185
|
break;
|
|
5144
5186
|
}
|
|
5145
|
-
}, [disabled, increment, decrement, decimal,
|
|
5187
|
+
}, [disabled, increment, decrement, decimal, formatDecimalValue, onChange, internalValue, minValue, maxValue]);
|
|
5146
5188
|
const inputSizeValue = inputSize !== undefined ? inputSize : Math.max(1, inputValue.length);
|
|
5147
5189
|
const uniqueId = useId();
|
|
5148
5190
|
const inputId = id || uniqueId;
|