@giro-ds/react 12.6.1 → 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 CHANGED
@@ -3927,8 +3927,21 @@ function validatePartialDate(value, locale = 'pt-br') {
3927
3927
  }
3928
3928
  return 'incomplete';
3929
3929
  }
3930
+ function startOfDay(date) {
3931
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
3932
+ }
3933
+ function isDateInRange(date, minDate, maxDate) {
3934
+ const day = startOfDay(date);
3935
+ if (minDate && day < startOfDay(minDate)) {
3936
+ return false;
3937
+ }
3938
+ if (maxDate && day > startOfDay(maxDate)) {
3939
+ return false;
3940
+ }
3941
+ return true;
3942
+ }
3930
3943
 
3931
- 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 }) => {
3944
+ 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 }) => {
3932
3945
  const fieldId = React.useId();
3933
3946
  const calendarId = `${fieldId}-calendar`;
3934
3947
  const containerStyle = { '--giro-scale': scale };
@@ -3937,31 +3950,40 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
3937
3950
  const [tempInputValue, setTempInputValue] = React.useState('');
3938
3951
  const [isEditing, setIsEditing] = React.useState(false);
3939
3952
  const [internalError, setInternalError] = React.useState('');
3940
- const [showCalendar, setShowCalendar] = React.useState(false);
3953
+ const [isCalendarOpen, setIsCalendarOpen] = React.useState(false);
3941
3954
  const [currentDate, setCurrentDate] = React.useState(new Date());
3942
3955
  const wrapperRef = React.useRef(null);
3943
3956
  const currentSelectedDate = isControlled ? value : internalDate;
3944
3957
  const hasValidationError = !!(externalError || internalError);
3945
3958
  const displayValue = isEditing ? tempInputValue : (currentSelectedDate ? formatDate(currentSelectedDate, locale) : '');
3946
- const combinedHelperText = externalError && helperText
3947
- ? `${helperText} • ${externalError}`
3948
- : externalError || helperText || '';
3959
+ const invalidDateMessage = locale === 'en-us' ? 'Invalid date' : 'Data inválida';
3960
+ const outOfRangeMessage = locale === 'en-us' ? 'Date out of allowed range' : 'Data fora do intervalo permitido';
3961
+ const internalErrorText = internalError === 'invalid'
3962
+ ? invalidDateMessage
3963
+ : internalError === 'range'
3964
+ ? outOfRangeMessage
3965
+ : '';
3966
+ const combinedHelperText = internalErrorText
3967
+ ? internalErrorText
3968
+ : externalError && helperText
3969
+ ? `${helperText} • ${externalError}`
3970
+ : externalError || helperText || '';
3949
3971
  React.useEffect(() => {
3950
3972
  function handleClickOutside(event) {
3951
3973
  const target = event.target;
3952
3974
  const isInsideWrapper = wrapperRef.current?.contains(target);
3953
3975
  const isInsideCalendar = !!target.closest?.('[data-radix-popper-content-wrapper]');
3954
3976
  if (!isInsideWrapper && !isInsideCalendar) {
3955
- setShowCalendar(false);
3977
+ setIsCalendarOpen(false);
3956
3978
  }
3957
3979
  }
3958
- if (showCalendar) {
3980
+ if (isCalendarOpen) {
3959
3981
  document.addEventListener('mousedown', handleClickOutside);
3960
3982
  }
3961
3983
  return () => {
3962
3984
  document.removeEventListener('mousedown', handleClickOutside);
3963
3985
  };
3964
- }, [showCalendar]);
3986
+ }, [isCalendarOpen]);
3965
3987
  const handleDateChange = React.useCallback((newDate) => {
3966
3988
  if (!isControlled) {
3967
3989
  setInternalDate(newDate);
@@ -3975,36 +3997,43 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
3975
3997
  }
3976
3998
  }, [isControlled, onChange]);
3977
3999
  const handleIconClick = () => {
3978
- setShowCalendar((prev) => !prev);
4000
+ if (!showCalendar)
4001
+ return;
4002
+ setIsCalendarOpen((prev) => !prev);
3979
4003
  };
3980
4004
  const handleKeyDown = (event) => {
3981
4005
  const { key } = event;
3982
4006
  if (key === 'Enter') {
3983
- if (showCalendar) {
4007
+ if (isCalendarOpen) {
3984
4008
  if (currentSelectedDate) {
3985
- setShowCalendar(false);
4009
+ setIsCalendarOpen(false);
3986
4010
  event.preventDefault();
3987
4011
  return;
3988
4012
  }
3989
4013
  if (tempInputValue.length === 10 && isValidDateFormat(tempInputValue, locale)) {
3990
4014
  const parsedDate = parseDate(tempInputValue, locale);
3991
4015
  if (parsedDate && !isNaN(parsedDate.getTime())) {
4016
+ if (!isDateInRange(parsedDate, minDate, maxDate)) {
4017
+ setInternalError('range');
4018
+ event.preventDefault();
4019
+ return;
4020
+ }
3992
4021
  handleDateChange(parsedDate);
3993
- setShowCalendar(false);
4022
+ setIsCalendarOpen(false);
3994
4023
  event.preventDefault();
3995
4024
  return;
3996
4025
  }
3997
4026
  }
3998
4027
  }
3999
- else {
4000
- setShowCalendar(true);
4028
+ else if (showCalendar) {
4029
+ setIsCalendarOpen(true);
4001
4030
  event.preventDefault();
4002
4031
  return;
4003
4032
  }
4004
4033
  }
4005
4034
  if (key === 'Escape') {
4006
- if (showCalendar) {
4007
- setShowCalendar(false);
4035
+ if (isCalendarOpen) {
4036
+ setIsCalendarOpen(false);
4008
4037
  event.preventDefault();
4009
4038
  return;
4010
4039
  }
@@ -4020,12 +4049,12 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
4020
4049
  }
4021
4050
  };
4022
4051
  const handleDaySelect = (newSelectedDate) => {
4023
- setShowCalendar(false);
4052
+ setIsCalendarOpen(false);
4024
4053
  handleDateChange(newSelectedDate);
4025
4054
  };
4026
4055
  const handleFocus = () => {
4027
- if (!disabled) {
4028
- setShowCalendar(true);
4056
+ if (!disabled && showCalendar) {
4057
+ setIsCalendarOpen(true);
4029
4058
  }
4030
4059
  };
4031
4060
  const handleTextFieldChange = (value) => {
@@ -4052,15 +4081,25 @@ const DatePicker = ({ locale = 'pt-br', calendarSide = 'bottom', calendarAlign =
4052
4081
  if (maskedValue.length === 10) {
4053
4082
  const parsedDate = parseDate(maskedValue, locale);
4054
4083
  if (parsedDate) {
4084
+ if (!isDateInRange(parsedDate, minDate, maxDate)) {
4085
+ setInternalError('range');
4086
+ if (!isControlled)
4087
+ setInternalDate(null);
4088
+ onChange?.(null);
4089
+ return;
4090
+ }
4055
4091
  handleDateChange(parsedDate);
4056
4092
  setCurrentDate(parsedDate);
4057
4093
  }
4058
4094
  }
4059
4095
  }
4060
4096
  };
4061
- return (jsxRuntime.jsx("div", { ref: wrapperRef, id: id, className: clsx(styles$h.datePicker, className), style: { ...containerStyle, ...style }, ...rest, children: jsxRuntime.jsx(Popover, { open: showCalendar, onOpenChange: setShowCalendar, asAnchor: true, trigger: jsxRuntime.jsx(TextField, { className: styles$h.textfieldContainer, type: "tel", icon: jsxRuntime.jsx(reactIcons.Calendar16Regular, { onClick: !disabled ? handleIconClick : undefined, className: clsx(styles$h.datePickerIcon, disabled && styles$h.datePickerIconDisabled) }), onChange: (e) => {
4097
+ return (jsxRuntime.jsx("div", { ref: wrapperRef, id: id, className: clsx(styles$h.datePicker, className), style: { ...containerStyle, ...style }, ...rest, children: jsxRuntime.jsx(Popover, { open: showCalendar && isCalendarOpen, onOpenChange: (open) => {
4098
+ if (showCalendar)
4099
+ setIsCalendarOpen(open);
4100
+ }, asAnchor: true, trigger: jsxRuntime.jsx(TextField, { className: styles$h.textfieldContainer, type: "tel", icon: jsxRuntime.jsx(reactIcons.Calendar16Regular, { onClick: !disabled ? handleIconClick : undefined, className: clsx(styles$h.datePickerIcon, disabled && styles$h.datePickerIconDisabled) }), onChange: (e) => {
4062
4101
  handleTextFieldChange(String(e));
4063
- }, onKeyDown: handleKeyDown, onFocus: handleFocus, autoComplete: "off", value: displayValue, helperText: !externalError ? (helperText || undefined) : undefined, errorMessage: externalError ? 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, "aria-controls": calendarId, "aria-invalid": hasValidationError, "aria-describedby": externalError ? undefined : (helperText ? `${fieldId}-help` : undefined) }), content: jsxRuntime.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: () => {
4102
+ }, 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: jsxRuntime.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: () => {
4064
4103
  handleDateChange(null);
4065
4104
  setCurrentDate(new Date());
4066
4105
  } }), side: calendarSide, align: calendarAlign, sideOffset: 8 }) }));
@@ -4071,7 +4110,7 @@ var styles$g = {"DialogOverlay":"Dialog-module__DialogOverlay___LEX2O","DialogCo
4071
4110
 
4072
4111
  const Dialog = ({ show = false, title, bodyContent, textPrimaryAction, textSecondaryAction, onPrimaryAction, onSecondaryAction, className, ...rest }) => (jsxRuntime.jsx(radixUi.AlertDialog.Root, { open: show, ...rest, children: jsxRuntime.jsxs(radixUi.AlertDialog.Portal, { children: [jsxRuntime.jsx(radixUi.AlertDialog.Overlay, { className: styles$g.DialogOverlay }), jsxRuntime.jsxs(radixUi.AlertDialog.Content, { className: clsx(styles$g.DialogContent, className), children: [jsxRuntime.jsx(radixUi.AlertDialog.Title, { className: styles$g.DialogTitle, children: title }), jsxRuntime.jsx(radixUi.AlertDialog.Description, { asChild: true, className: styles$g.DialogDescription, children: jsxRuntime.jsx("div", { children: bodyContent }) }), jsxRuntime.jsxs("div", { className: styles$g.DivButtons, children: [!!(textSecondaryAction && textSecondaryAction.trim()) && (jsxRuntime.jsx(radixUi.AlertDialog.Cancel, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "outlined", ...(onSecondaryAction && { onClick: onSecondaryAction }), children: textSecondaryAction }) })), jsxRuntime.jsx(radixUi.AlertDialog.Action, { asChild: true, children: jsxRuntime.jsx(Button, { variant: "filled", ...(onPrimaryAction && { onClick: onPrimaryAction }), children: textPrimaryAction }) })] })] })] }) }));
4073
4112
 
4074
- var styles$f = {"drawerShadow":"Drawer-module__drawerShadow___0Z6iL","drawerShadow--visible":"Drawer-module__drawerShadow--visible___FspoH","drawerSidebar":"Drawer-module__drawerSidebar___cdyyb","drawerSidebar--open":"Drawer-module__drawerSidebar--open___ee2-Y","drawerSidebar--disabled":"Drawer-module__drawerSidebar--disabled___MYrBI","drawerTitleClose":"Drawer-module__drawerTitleClose___QzqN-","drawerTitle":"Drawer-module__drawerTitle___naMX0","drawerChildren":"Drawer-module__drawerChildren___xGdg9","drawerHeaderContent":"Drawer-module__drawerHeaderContent___NLSwj"};
4113
+ var styles$f = {"drawerShadow":"Drawer-module__drawerShadow___0Z6iL","drawerShadow--visible":"Drawer-module__drawerShadow--visible___FspoH","drawerSidebar":"Drawer-module__drawerSidebar___cdyyb","drawerSidebar--open":"Drawer-module__drawerSidebar--open___ee2-Y","drawerSidebar--disabled":"Drawer-module__drawerSidebar--disabled___MYrBI","drawerTitleClose":"Drawer-module__drawerTitleClose___QzqN-","drawerTitle":"Drawer-module__drawerTitle___naMX0","drawerChildren":"Drawer-module__drawerChildren___xGdg9","drawerHeaderContent":"Drawer-module__drawerHeaderContent___NLSwj","drawerFooter":"Drawer-module__drawerFooter___qGaC-"};
4075
4114
 
4076
4115
  const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClose, title = 'Título', isOpen = false, onOpen, className, id, disabled = false, onOverlayClick, closeOnOverlayClick = true, closeOnEscape = true, ...rest }) => {
4077
4116
  const internalClose = React.useCallback(() => {
@@ -4120,6 +4159,25 @@ const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClos
4120
4159
  event.stopPropagation();
4121
4160
  internalClose();
4122
4161
  };
4162
+ const contentRef = React.useRef(null);
4163
+ const [scrollbarWidth, setScrollbarWidth] = React.useState(0);
4164
+ React.useEffect(() => {
4165
+ const contentEl = contentRef.current;
4166
+ if (!contentEl)
4167
+ return;
4168
+ const measureScrollbar = () => {
4169
+ setScrollbarWidth(contentEl.offsetWidth - contentEl.clientWidth);
4170
+ };
4171
+ measureScrollbar();
4172
+ const resizeObserver = new ResizeObserver(measureScrollbar);
4173
+ resizeObserver.observe(contentEl);
4174
+ const mutationObserver = new MutationObserver(measureScrollbar);
4175
+ mutationObserver.observe(contentEl, { childList: true, subtree: true, characterData: true });
4176
+ return () => {
4177
+ resizeObserver.disconnect();
4178
+ mutationObserver.disconnect();
4179
+ };
4180
+ }, [isOpen, children]);
4123
4181
  return reactDom.createPortal(jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: clsx(styles$f['drawerShadow'], {
4124
4182
  [styles$f['drawerShadow--visible']]: isOpen,
4125
4183
  }), onClick: handleOverlayClick, role: "presentation", "aria-hidden": "true", "data-testid": "drawer-overlay" }), jsxRuntime.jsxs("div", { className: clsx(styles$f['drawerSidebar'], {
@@ -4127,7 +4185,8 @@ const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClos
4127
4185
  [styles$f['drawerSidebar--disabled']]: disabled,
4128
4186
  }, className), style: {
4129
4187
  '--drawer-custom-width': customWidth,
4130
- }, onClick: handleDrawerClick, role: "dialog", "aria-modal": "true", "aria-labelledby": id ? `${id}-title` : 'drawer-title', "aria-hidden": !isOpen, "data-testid": "drawer-panel", id: id, ...rest, children: [jsxRuntime.jsxs("div", { className: styles$f.drawerTitleClose, children: [jsxRuntime.jsx("div", { className: styles$f.drawerTitle, id: id ? `${id}-title` : 'drawer-title', children: title }), headerContent && (jsxRuntime.jsx("div", { className: styles$f.drawerHeaderContent, children: headerContent })), jsxRuntime.jsx(Button, { onClick: handleCloseClick, variant: 'outlined', iconOnly: true, icon: jsxRuntime.jsx(reactIcons.Dismiss16Regular, {}), size: 'lg', tooltipText: 'Fechar' })] }), jsxRuntime.jsx("div", { className: styles$f.drawerChildren, "data-testid": "drawer-content", children: children }), footer] })] }), document.body);
4188
+ '--drawer-scrollbar-width': `${scrollbarWidth}px`,
4189
+ }, onClick: handleDrawerClick, role: "dialog", "aria-modal": "true", "aria-labelledby": id ? `${id}-title` : 'drawer-title', "aria-hidden": !isOpen, "data-testid": "drawer-panel", id: id, ...rest, children: [jsxRuntime.jsxs("div", { className: styles$f.drawerTitleClose, children: [jsxRuntime.jsx("div", { className: styles$f.drawerTitle, id: id ? `${id}-title` : 'drawer-title', children: title }), headerContent && (jsxRuntime.jsx("div", { className: styles$f.drawerHeaderContent, children: headerContent })), jsxRuntime.jsx(Button, { onClick: handleCloseClick, variant: 'outlined', iconOnly: true, icon: jsxRuntime.jsx(reactIcons.Dismiss16Regular, {}), size: 'lg', tooltipText: 'Fechar' })] }), jsxRuntime.jsx("div", { ref: contentRef, className: styles$f.drawerChildren, "data-testid": "drawer-content", children: children }), footer && (jsxRuntime.jsx("div", { className: styles$f.drawerFooter, children: footer }))] })] }), document.body);
4131
4190
  };
4132
4191
 
4133
4192
  var styles$e = {"container":"FileUpload-module__container___hFeKV","dropZone":"FileUpload-module__dropZone___716hF","disabled":"FileUpload-module__disabled___mwePo","alert":"FileUpload-module__alert___Dnzqc","dragging":"FileUpload-module__dragging___XZghy","emptyState":"FileUpload-module__emptyState___6Ll9D","uploadIcon":"FileUpload-module__uploadIcon___MkBLe","uploadText":"FileUpload-module__uploadText___VWc9g","alertIcon":"FileUpload-module__alertIcon___pTaMS","alertText":"FileUpload-module__alertText___sfV4z","fileList":"FileUpload-module__fileList___K6KQD","thumb":"FileUpload-module__thumb___eg59D","removeButton":"FileUpload-module__removeButton___jUFNv","thumbClip":"FileUpload-module__thumbClip___sP9wp","thumbImage":"FileUpload-module__thumbImage___Swxhd","thumbFile":"FileUpload-module__thumbFile___y7lg5","thumbFileName":"FileUpload-module__thumbFileName___LPSCX","helperText":"FileUpload-module__helperText___DzPqP","errorText":"FileUpload-module__errorText___cHd1Z"};
@@ -4966,11 +5025,12 @@ const Modal = ({ isOpen = false, onClose, title, children, headerContent, closeO
4966
5025
 
4967
5026
  var styles$8 = {"quantity":"Quantity-module__quantity___-vndR","quantityInput":"Quantity-module__quantityInput___xZG-v","disabled":"Quantity-module__disabled___X6p5l"};
4968
5027
 
4969
- 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 }) => {
5028
+ 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 }) => {
4970
5029
  const initialValue = Math.min(Math.max(value, minValue), maxValue);
4971
5030
  const [internalValue, setInternalValue] = React.useState(initialValue);
4972
- const [inputValue, setInputValue] = React.useState(decimal ? initialValue.toFixed(decimalPlaces) : String(initialValue));
5031
+ const [inputValue, setInputValue] = React.useState(decimal ? initialValue.toFixed(decimalPlaces).replace('.', decimalSeparator) : String(initialValue));
4973
5032
  const inputRef = React.useRef(null);
5033
+ const formatDecimalValue = React.useCallback((num) => num.toFixed(decimalPlaces).replace('.', decimalSeparator), [decimalPlaces, decimalSeparator]);
4974
5034
  const stepValue = valueIncrement !== undefined ? valueIncrement : decimal ? Math.pow(10, -decimalPlaces) : 1;
4975
5035
  const isMinValue = React.useMemo(() => internalValue <= minValue, [internalValue, minValue]);
4976
5036
  const isMaxValue = React.useMemo(() => internalValue >= maxValue, [internalValue, maxValue]);
@@ -4988,32 +5048,34 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
4988
5048
  React.useEffect(() => {
4989
5049
  const clamped = Math.min(Math.max(value, minValue), maxValue);
4990
5050
  setInternalValue(clamped);
4991
- setInputValue(decimal ? clamped.toFixed(decimalPlaces) : String(clamped));
4992
- }, [value, minValue, maxValue, decimal, decimalPlaces]);
5051
+ setInputValue(decimal ? formatDecimalValue(clamped) : String(clamped));
5052
+ }, [value, minValue, maxValue, decimal, formatDecimalValue]);
4993
5053
  const increment = React.useCallback(() => {
4994
5054
  if (disabled)
4995
5055
  return;
4996
5056
  const newValue = Math.min(maxValue, internalValue + stepValue);
4997
5057
  setInternalValue(newValue);
4998
- setInputValue(decimal ? newValue.toFixed(decimalPlaces) : String(newValue));
5058
+ setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
4999
5059
  onChange?.(newValue);
5000
- }, [disabled, internalValue, stepValue, decimal, decimalPlaces, onChange, maxValue]);
5060
+ }, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, maxValue]);
5001
5061
  const decrement = React.useCallback(() => {
5002
5062
  if (disabled)
5003
5063
  return;
5004
5064
  const newValue = Math.max(minValue, internalValue - stepValue);
5005
5065
  setInternalValue(newValue);
5006
- setInputValue(decimal ? newValue.toFixed(decimalPlaces) : String(newValue));
5066
+ setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
5007
5067
  onChange?.(newValue);
5008
- }, [disabled, internalValue, stepValue, decimal, decimalPlaces, onChange, minValue]);
5068
+ }, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, minValue]);
5009
5069
  const filterInput = React.useCallback((inputValue) => {
5010
5070
  if (decimal) {
5011
- let filtered = inputValue.replace(/[^\d.]/g, '');
5012
- const parts = filtered.split('.');
5071
+ const escapedSeparator = decimalSeparator.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
5072
+ const allowedCharsRegex = new RegExp(`[^\\d${escapedSeparator}]`, 'g');
5073
+ let filtered = inputValue.replace(allowedCharsRegex, '');
5074
+ const parts = filtered.split(decimalSeparator);
5013
5075
  if (parts.length > 2) {
5014
- filtered = parts[0] + '.' + parts.slice(1).join('');
5076
+ filtered = parts[0] + decimalSeparator + parts.slice(1).join('');
5015
5077
  }
5016
- if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith('0.')) {
5078
+ if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith(`0${decimalSeparator}`)) {
5017
5079
  filtered = filtered.replace(/^0+/, '');
5018
5080
  }
5019
5081
  return filtered;
@@ -5025,22 +5087,22 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5025
5087
  }
5026
5088
  return filtered || '0'; // Se ficar vazio, retorna '0'
5027
5089
  }
5028
- }, [decimal]);
5090
+ }, [decimal, decimalSeparator]);
5029
5091
  const handleInputChange = React.useCallback((event) => {
5030
5092
  if (disabled)
5031
5093
  return;
5032
5094
  const rawValue = event.target.value;
5033
5095
  const filteredValue = filterInput(rawValue);
5034
5096
  setInputValue(filteredValue);
5035
- if (filteredValue === '' || filteredValue === '.') {
5097
+ if (filteredValue === '' || filteredValue === decimalSeparator) {
5036
5098
  onChange?.(0);
5037
5099
  return;
5038
5100
  }
5039
5101
  if (decimal) {
5040
- if (filteredValue.endsWith('.')) {
5102
+ if (filteredValue.endsWith(decimalSeparator)) {
5041
5103
  return;
5042
5104
  }
5043
- const parsedValue = parseFloat(filteredValue);
5105
+ const parsedValue = parseFloat(filteredValue.replace(decimalSeparator, '.'));
5044
5106
  if (!isNaN(parsedValue)) {
5045
5107
  onChange?.(parsedValue);
5046
5108
  }
@@ -5052,36 +5114,36 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5052
5114
  onChange?.(validValue);
5053
5115
  }
5054
5116
  }
5055
- }, [disabled, decimal, filterInput, onChange, minValue, maxValue]);
5117
+ }, [disabled, decimal, decimalSeparator, filterInput, onChange, minValue, maxValue]);
5056
5118
  const handleBlur = React.useCallback(() => {
5057
5119
  if (disabled)
5058
5120
  return;
5059
5121
  const currentValue = inputValue.trim();
5060
5122
  if (decimal) {
5061
- if (currentValue === '' || currentValue === '.') {
5062
- setInputValue(internalValue.toFixed(decimalPlaces));
5123
+ if (currentValue === '' || currentValue === decimalSeparator) {
5124
+ setInputValue(formatDecimalValue(internalValue));
5063
5125
  return;
5064
5126
  }
5065
- if (currentValue.endsWith('.')) {
5066
- const baseValue = parseFloat(currentValue.slice(0, -1));
5127
+ if (currentValue.endsWith(decimalSeparator)) {
5128
+ const baseValue = parseFloat(currentValue.slice(0, -1).replace(decimalSeparator, '.'));
5067
5129
  if (!isNaN(baseValue)) {
5068
- const formattedValue = baseValue.toFixed(decimalPlaces);
5130
+ const formattedValue = formatDecimalValue(baseValue);
5069
5131
  setInputValue(formattedValue);
5070
5132
  setInternalValue(baseValue);
5071
5133
  onChange?.(baseValue);
5072
5134
  }
5073
5135
  return;
5074
5136
  }
5075
- const parsedValue = parseFloat(currentValue);
5137
+ const parsedValue = parseFloat(currentValue.replace(decimalSeparator, '.'));
5076
5138
  if (!isNaN(parsedValue)) {
5077
5139
  const normalizedValue = Math.min(Math.max(parsedValue, minValue), maxValue);
5078
- const formattedValue = normalizedValue.toFixed(decimalPlaces);
5140
+ const formattedValue = formatDecimalValue(normalizedValue);
5079
5141
  setInputValue(formattedValue);
5080
5142
  setInternalValue(normalizedValue);
5081
5143
  onChange?.(normalizedValue);
5082
5144
  }
5083
5145
  else {
5084
- setInputValue(internalValue.toFixed(decimalPlaces));
5146
+ setInputValue(formatDecimalValue(internalValue));
5085
5147
  }
5086
5148
  }
5087
5149
  else {
@@ -5100,7 +5162,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5100
5162
  onChange?.(normalizedValue);
5101
5163
  }
5102
5164
  }
5103
- }, [disabled, decimal, inputValue, decimalPlaces, internalValue, onChange, minValue, maxValue]);
5165
+ }, [disabled, decimal, decimalSeparator, inputValue, formatDecimalValue, internalValue, onChange, minValue, maxValue]);
5104
5166
  const handleInputKeyDown = React.useCallback((e) => {
5105
5167
  if (disabled)
5106
5168
  return;
@@ -5122,14 +5184,14 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5122
5184
  case 'Escape':
5123
5185
  e.preventDefault();
5124
5186
  if (inputRef.current) {
5125
- setInputValue(decimal ? internalValue.toFixed(decimalPlaces) : String(internalValue));
5187
+ setInputValue(decimal ? formatDecimalValue(internalValue) : String(internalValue));
5126
5188
  inputRef.current.blur();
5127
5189
  }
5128
5190
  break;
5129
5191
  case 'Home':
5130
5192
  e.preventDefault();
5131
5193
  setInternalValue(minValue);
5132
- setInputValue(decimal ? minValue.toFixed(decimalPlaces) : String(minValue));
5194
+ setInputValue(decimal ? formatDecimalValue(minValue) : String(minValue));
5133
5195
  onChange?.(minValue);
5134
5196
  break;
5135
5197
  case 'End':
@@ -5141,7 +5203,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5141
5203
  }
5142
5204
  break;
5143
5205
  }
5144
- }, [disabled, increment, decrement, decimal, decimalPlaces, onChange, internalValue, minValue, maxValue]);
5206
+ }, [disabled, increment, decrement, decimal, formatDecimalValue, onChange, internalValue, minValue, maxValue]);
5145
5207
  const inputSizeValue = inputSize !== undefined ? inputSize : Math.max(1, inputValue.length);
5146
5208
  const uniqueId = React.useId();
5147
5209
  const inputId = id || uniqueId;
@@ -6150,11 +6212,17 @@ ToastProvider.displayName = 'ToastProvider';
6150
6212
  */
6151
6213
  const ToastContainer = () => {
6152
6214
  const { toasts } = useToastContext();
6215
+ const portalRef = React__namespace.useRef(null);
6216
+ React__namespace.useEffect(() => {
6217
+ if (toasts.length > 0 && portalRef.current) {
6218
+ document.body.appendChild(portalRef.current);
6219
+ }
6220
+ }, [toasts.length]);
6153
6221
  return (jsxRuntime.jsxs(radixUi.Toast.Provider, { swipeDirection: "left", children: [toasts.map((toast) => {
6154
6222
  if (!toast.id)
6155
6223
  return null;
6156
6224
  return jsxRuntime.jsx(Toast, { id: toast.id, ...toast }, toast.id);
6157
- }), jsxRuntime.jsx(radixUi.Toast.Viewport, { className: styles$2.toastViewport })] }));
6225
+ }), jsxRuntime.jsx(radixUi.Portal.Root, { ref: portalRef, children: jsxRuntime.jsx(radixUi.Toast.Viewport, { className: styles$2.toastViewport }) })] }));
6158
6226
  };
6159
6227
  ToastContainer.displayName = 'ToastContainer';
6160
6228