@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.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
@@ -1,11 +1,11 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import clsx from 'clsx';
3
- import { Avatar as Avatar$1, Tooltip as Tooltip$1, Checkbox as Checkbox$1, Popover as Popover$1, Label, AlertDialog, DropdownMenu, Dialog as Dialog$1, RadioGroup, Select as Select$1, Toggle as Toggle$1, ToggleGroup as ToggleGroup$1, Toast as Toast$1, Switch as Switch$1, unstable_OneTimePasswordField } from 'radix-ui';
3
+ import { Avatar as Avatar$1, Tooltip as Tooltip$1, Checkbox as Checkbox$1, Popover as Popover$1, Label, AlertDialog, DropdownMenu, Dialog as Dialog$1, RadioGroup, Select as Select$1, Toggle as Toggle$1, ToggleGroup as ToggleGroup$1, Toast as Toast$1, Portal, Switch as Switch$1, unstable_OneTimePasswordField } from 'radix-ui';
4
4
  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 [showCalendar, setShowCalendar] = useState(false);
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 combinedHelperText = externalError && helperText
3928
- ? `${helperText} • ${externalError}`
3929
- : externalError || helperText || '';
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
- setShowCalendar(false);
3958
+ setIsCalendarOpen(false);
3937
3959
  }
3938
3960
  }
3939
- if (showCalendar) {
3961
+ if (isCalendarOpen) {
3940
3962
  document.addEventListener('mousedown', handleClickOutside);
3941
3963
  }
3942
3964
  return () => {
3943
3965
  document.removeEventListener('mousedown', handleClickOutside);
3944
3966
  };
3945
- }, [showCalendar]);
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
- setShowCalendar((prev) => !prev);
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 (showCalendar) {
3988
+ if (isCalendarOpen) {
3965
3989
  if (currentSelectedDate) {
3966
- setShowCalendar(false);
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
- setShowCalendar(false);
4003
+ setIsCalendarOpen(false);
3975
4004
  event.preventDefault();
3976
4005
  return;
3977
4006
  }
3978
4007
  }
3979
4008
  }
3980
- else {
3981
- setShowCalendar(true);
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 (showCalendar) {
3988
- setShowCalendar(false);
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
- setShowCalendar(false);
4033
+ setIsCalendarOpen(false);
4005
4034
  handleDateChange(newSelectedDate);
4006
4035
  };
4007
4036
  const handleFocus = () => {
4008
- if (!disabled) {
4009
- setShowCalendar(true);
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, onOpenChange: setShowCalendar, 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) => {
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: !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: 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: () => {
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 }) }));
@@ -4052,7 +4091,7 @@ var styles$g = {"DialogOverlay":"Dialog-module__DialogOverlay___LEX2O","DialogCo
4052
4091
 
4053
4092
  const Dialog = ({ show = false, title, bodyContent, textPrimaryAction, textSecondaryAction, onPrimaryAction, onSecondaryAction, className, ...rest }) => (jsx(AlertDialog.Root, { open: show, ...rest, children: jsxs(AlertDialog.Portal, { children: [jsx(AlertDialog.Overlay, { className: styles$g.DialogOverlay }), jsxs(AlertDialog.Content, { className: clsx(styles$g.DialogContent, className), children: [jsx(AlertDialog.Title, { className: styles$g.DialogTitle, children: title }), jsx(AlertDialog.Description, { asChild: true, className: styles$g.DialogDescription, children: jsx("div", { children: bodyContent }) }), jsxs("div", { className: styles$g.DivButtons, children: [!!(textSecondaryAction && textSecondaryAction.trim()) && (jsx(AlertDialog.Cancel, { asChild: true, children: jsx(Button, { variant: "outlined", ...(onSecondaryAction && { onClick: onSecondaryAction }), children: textSecondaryAction }) })), jsx(AlertDialog.Action, { asChild: true, children: jsx(Button, { variant: "filled", ...(onPrimaryAction && { onClick: onPrimaryAction }), children: textPrimaryAction }) })] })] })] }) }));
4054
4093
 
4055
- 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"};
4094
+ 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-"};
4056
4095
 
4057
4096
  const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClose, title = 'Título', isOpen = false, onOpen, className, id, disabled = false, onOverlayClick, closeOnOverlayClick = true, closeOnEscape = true, ...rest }) => {
4058
4097
  const internalClose = useCallback(() => {
@@ -4101,6 +4140,25 @@ const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClos
4101
4140
  event.stopPropagation();
4102
4141
  internalClose();
4103
4142
  };
4143
+ const contentRef = useRef(null);
4144
+ const [scrollbarWidth, setScrollbarWidth] = useState(0);
4145
+ useEffect(() => {
4146
+ const contentEl = contentRef.current;
4147
+ if (!contentEl)
4148
+ return;
4149
+ const measureScrollbar = () => {
4150
+ setScrollbarWidth(contentEl.offsetWidth - contentEl.clientWidth);
4151
+ };
4152
+ measureScrollbar();
4153
+ const resizeObserver = new ResizeObserver(measureScrollbar);
4154
+ resizeObserver.observe(contentEl);
4155
+ const mutationObserver = new MutationObserver(measureScrollbar);
4156
+ mutationObserver.observe(contentEl, { childList: true, subtree: true, characterData: true });
4157
+ return () => {
4158
+ resizeObserver.disconnect();
4159
+ mutationObserver.disconnect();
4160
+ };
4161
+ }, [isOpen, children]);
4104
4162
  return createPortal(jsxs(Fragment, { children: [jsx("div", { className: clsx(styles$f['drawerShadow'], {
4105
4163
  [styles$f['drawerShadow--visible']]: isOpen,
4106
4164
  }), onClick: handleOverlayClick, role: "presentation", "aria-hidden": "true", "data-testid": "drawer-overlay" }), jsxs("div", { className: clsx(styles$f['drawerSidebar'], {
@@ -4108,7 +4166,8 @@ const Drawer = ({ children, headerContent, footer, customWidth = '400px', onClos
4108
4166
  [styles$f['drawerSidebar--disabled']]: disabled,
4109
4167
  }, className), style: {
4110
4168
  '--drawer-custom-width': customWidth,
4111
- }, 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: [jsxs("div", { className: styles$f.drawerTitleClose, children: [jsx("div", { className: styles$f.drawerTitle, id: id ? `${id}-title` : 'drawer-title', children: title }), headerContent && (jsx("div", { className: styles$f.drawerHeaderContent, children: headerContent })), jsx(Button, { onClick: handleCloseClick, variant: 'outlined', iconOnly: true, icon: jsx(Dismiss16Regular, {}), size: 'lg', tooltipText: 'Fechar' })] }), jsx("div", { className: styles$f.drawerChildren, "data-testid": "drawer-content", children: children }), footer] })] }), document.body);
4169
+ '--drawer-scrollbar-width': `${scrollbarWidth}px`,
4170
+ }, 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: [jsxs("div", { className: styles$f.drawerTitleClose, children: [jsx("div", { className: styles$f.drawerTitle, id: id ? `${id}-title` : 'drawer-title', children: title }), headerContent && (jsx("div", { className: styles$f.drawerHeaderContent, children: headerContent })), jsx(Button, { onClick: handleCloseClick, variant: 'outlined', iconOnly: true, icon: jsx(Dismiss16Regular, {}), size: 'lg', tooltipText: 'Fechar' })] }), jsx("div", { ref: contentRef, className: styles$f.drawerChildren, "data-testid": "drawer-content", children: children }), footer && (jsx("div", { className: styles$f.drawerFooter, children: footer }))] })] }), document.body);
4112
4171
  };
4113
4172
 
4114
4173
  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"};
@@ -4947,11 +5006,12 @@ const Modal = ({ isOpen = false, onClose, title, children, headerContent, closeO
4947
5006
 
4948
5007
  var styles$8 = {"quantity":"Quantity-module__quantity___-vndR","quantityInput":"Quantity-module__quantityInput___xZG-v","disabled":"Quantity-module__disabled___X6p5l"};
4949
5008
 
4950
- 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 }) => {
4951
5010
  const initialValue = Math.min(Math.max(value, minValue), maxValue);
4952
5011
  const [internalValue, setInternalValue] = useState(initialValue);
4953
- const [inputValue, setInputValue] = useState(decimal ? initialValue.toFixed(decimalPlaces) : String(initialValue));
5012
+ const [inputValue, setInputValue] = useState(decimal ? initialValue.toFixed(decimalPlaces).replace('.', decimalSeparator) : String(initialValue));
4954
5013
  const inputRef = useRef(null);
5014
+ const formatDecimalValue = useCallback((num) => num.toFixed(decimalPlaces).replace('.', decimalSeparator), [decimalPlaces, decimalSeparator]);
4955
5015
  const stepValue = valueIncrement !== undefined ? valueIncrement : decimal ? Math.pow(10, -decimalPlaces) : 1;
4956
5016
  const isMinValue = useMemo(() => internalValue <= minValue, [internalValue, minValue]);
4957
5017
  const isMaxValue = useMemo(() => internalValue >= maxValue, [internalValue, maxValue]);
@@ -4969,32 +5029,34 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
4969
5029
  useEffect(() => {
4970
5030
  const clamped = Math.min(Math.max(value, minValue), maxValue);
4971
5031
  setInternalValue(clamped);
4972
- setInputValue(decimal ? clamped.toFixed(decimalPlaces) : String(clamped));
4973
- }, [value, minValue, maxValue, decimal, decimalPlaces]);
5032
+ setInputValue(decimal ? formatDecimalValue(clamped) : String(clamped));
5033
+ }, [value, minValue, maxValue, decimal, formatDecimalValue]);
4974
5034
  const increment = useCallback(() => {
4975
5035
  if (disabled)
4976
5036
  return;
4977
5037
  const newValue = Math.min(maxValue, internalValue + stepValue);
4978
5038
  setInternalValue(newValue);
4979
- setInputValue(decimal ? newValue.toFixed(decimalPlaces) : String(newValue));
5039
+ setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
4980
5040
  onChange?.(newValue);
4981
- }, [disabled, internalValue, stepValue, decimal, decimalPlaces, onChange, maxValue]);
5041
+ }, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, maxValue]);
4982
5042
  const decrement = useCallback(() => {
4983
5043
  if (disabled)
4984
5044
  return;
4985
5045
  const newValue = Math.max(minValue, internalValue - stepValue);
4986
5046
  setInternalValue(newValue);
4987
- setInputValue(decimal ? newValue.toFixed(decimalPlaces) : String(newValue));
5047
+ setInputValue(decimal ? formatDecimalValue(newValue) : String(newValue));
4988
5048
  onChange?.(newValue);
4989
- }, [disabled, internalValue, stepValue, decimal, decimalPlaces, onChange, minValue]);
5049
+ }, [disabled, internalValue, stepValue, decimal, formatDecimalValue, onChange, minValue]);
4990
5050
  const filterInput = useCallback((inputValue) => {
4991
5051
  if (decimal) {
4992
- let filtered = inputValue.replace(/[^\d.]/g, '');
4993
- const parts = filtered.split('.');
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);
4994
5056
  if (parts.length > 2) {
4995
- filtered = parts[0] + '.' + parts.slice(1).join('');
5057
+ filtered = parts[0] + decimalSeparator + parts.slice(1).join('');
4996
5058
  }
4997
- if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith('0.')) {
5059
+ if (filtered.length > 1 && filtered.startsWith('0') && !filtered.startsWith(`0${decimalSeparator}`)) {
4998
5060
  filtered = filtered.replace(/^0+/, '');
4999
5061
  }
5000
5062
  return filtered;
@@ -5006,22 +5068,22 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5006
5068
  }
5007
5069
  return filtered || '0'; // Se ficar vazio, retorna '0'
5008
5070
  }
5009
- }, [decimal]);
5071
+ }, [decimal, decimalSeparator]);
5010
5072
  const handleInputChange = useCallback((event) => {
5011
5073
  if (disabled)
5012
5074
  return;
5013
5075
  const rawValue = event.target.value;
5014
5076
  const filteredValue = filterInput(rawValue);
5015
5077
  setInputValue(filteredValue);
5016
- if (filteredValue === '' || filteredValue === '.') {
5078
+ if (filteredValue === '' || filteredValue === decimalSeparator) {
5017
5079
  onChange?.(0);
5018
5080
  return;
5019
5081
  }
5020
5082
  if (decimal) {
5021
- if (filteredValue.endsWith('.')) {
5083
+ if (filteredValue.endsWith(decimalSeparator)) {
5022
5084
  return;
5023
5085
  }
5024
- const parsedValue = parseFloat(filteredValue);
5086
+ const parsedValue = parseFloat(filteredValue.replace(decimalSeparator, '.'));
5025
5087
  if (!isNaN(parsedValue)) {
5026
5088
  onChange?.(parsedValue);
5027
5089
  }
@@ -5033,36 +5095,36 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5033
5095
  onChange?.(validValue);
5034
5096
  }
5035
5097
  }
5036
- }, [disabled, decimal, filterInput, onChange, minValue, maxValue]);
5098
+ }, [disabled, decimal, decimalSeparator, filterInput, onChange, minValue, maxValue]);
5037
5099
  const handleBlur = useCallback(() => {
5038
5100
  if (disabled)
5039
5101
  return;
5040
5102
  const currentValue = inputValue.trim();
5041
5103
  if (decimal) {
5042
- if (currentValue === '' || currentValue === '.') {
5043
- setInputValue(internalValue.toFixed(decimalPlaces));
5104
+ if (currentValue === '' || currentValue === decimalSeparator) {
5105
+ setInputValue(formatDecimalValue(internalValue));
5044
5106
  return;
5045
5107
  }
5046
- if (currentValue.endsWith('.')) {
5047
- const baseValue = parseFloat(currentValue.slice(0, -1));
5108
+ if (currentValue.endsWith(decimalSeparator)) {
5109
+ const baseValue = parseFloat(currentValue.slice(0, -1).replace(decimalSeparator, '.'));
5048
5110
  if (!isNaN(baseValue)) {
5049
- const formattedValue = baseValue.toFixed(decimalPlaces);
5111
+ const formattedValue = formatDecimalValue(baseValue);
5050
5112
  setInputValue(formattedValue);
5051
5113
  setInternalValue(baseValue);
5052
5114
  onChange?.(baseValue);
5053
5115
  }
5054
5116
  return;
5055
5117
  }
5056
- const parsedValue = parseFloat(currentValue);
5118
+ const parsedValue = parseFloat(currentValue.replace(decimalSeparator, '.'));
5057
5119
  if (!isNaN(parsedValue)) {
5058
5120
  const normalizedValue = Math.min(Math.max(parsedValue, minValue), maxValue);
5059
- const formattedValue = normalizedValue.toFixed(decimalPlaces);
5121
+ const formattedValue = formatDecimalValue(normalizedValue);
5060
5122
  setInputValue(formattedValue);
5061
5123
  setInternalValue(normalizedValue);
5062
5124
  onChange?.(normalizedValue);
5063
5125
  }
5064
5126
  else {
5065
- setInputValue(internalValue.toFixed(decimalPlaces));
5127
+ setInputValue(formatDecimalValue(internalValue));
5066
5128
  }
5067
5129
  }
5068
5130
  else {
@@ -5081,7 +5143,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5081
5143
  onChange?.(normalizedValue);
5082
5144
  }
5083
5145
  }
5084
- }, [disabled, decimal, inputValue, decimalPlaces, internalValue, onChange, minValue, maxValue]);
5146
+ }, [disabled, decimal, decimalSeparator, inputValue, formatDecimalValue, internalValue, onChange, minValue, maxValue]);
5085
5147
  const handleInputKeyDown = useCallback((e) => {
5086
5148
  if (disabled)
5087
5149
  return;
@@ -5103,14 +5165,14 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5103
5165
  case 'Escape':
5104
5166
  e.preventDefault();
5105
5167
  if (inputRef.current) {
5106
- setInputValue(decimal ? internalValue.toFixed(decimalPlaces) : String(internalValue));
5168
+ setInputValue(decimal ? formatDecimalValue(internalValue) : String(internalValue));
5107
5169
  inputRef.current.blur();
5108
5170
  }
5109
5171
  break;
5110
5172
  case 'Home':
5111
5173
  e.preventDefault();
5112
5174
  setInternalValue(minValue);
5113
- setInputValue(decimal ? minValue.toFixed(decimalPlaces) : String(minValue));
5175
+ setInputValue(decimal ? formatDecimalValue(minValue) : String(minValue));
5114
5176
  onChange?.(minValue);
5115
5177
  break;
5116
5178
  case 'End':
@@ -5122,7 +5184,7 @@ const Quantity = ({ value = 0, onChange, disabled = false, decimal = false, deci
5122
5184
  }
5123
5185
  break;
5124
5186
  }
5125
- }, [disabled, increment, decrement, decimal, decimalPlaces, onChange, internalValue, minValue, maxValue]);
5187
+ }, [disabled, increment, decrement, decimal, formatDecimalValue, onChange, internalValue, minValue, maxValue]);
5126
5188
  const inputSizeValue = inputSize !== undefined ? inputSize : Math.max(1, inputValue.length);
5127
5189
  const uniqueId = useId();
5128
5190
  const inputId = id || uniqueId;
@@ -6131,11 +6193,17 @@ ToastProvider.displayName = 'ToastProvider';
6131
6193
  */
6132
6194
  const ToastContainer = () => {
6133
6195
  const { toasts } = useToastContext();
6196
+ const portalRef = React.useRef(null);
6197
+ React.useEffect(() => {
6198
+ if (toasts.length > 0 && portalRef.current) {
6199
+ document.body.appendChild(portalRef.current);
6200
+ }
6201
+ }, [toasts.length]);
6134
6202
  return (jsxs(Toast$1.Provider, { swipeDirection: "left", children: [toasts.map((toast) => {
6135
6203
  if (!toast.id)
6136
6204
  return null;
6137
6205
  return jsx(Toast, { id: toast.id, ...toast }, toast.id);
6138
- }), jsx(Toast$1.Viewport, { className: styles$2.toastViewport })] }));
6206
+ }), jsx(Portal.Root, { ref: portalRef, children: jsx(Toast$1.Viewport, { className: styles$2.toastViewport }) })] }));
6139
6207
  };
6140
6208
  ToastContainer.displayName = 'ToastContainer';
6141
6209