@pagamio/frontend-commons-lib 0.8.238 → 0.8.239

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.
@@ -3,33 +3,40 @@ import { DayPicker } from 'react-day-picker';
3
3
  import { cn } from '../../helpers';
4
4
  import { variantStyles } from '../ui';
5
5
  const Calendar = ({ className, classNames, showOutsideDays = true, ...props }) => {
6
- return (_jsx(DayPicker, { showOutsideDays: showOutsideDays, className: cn('p-3', className), classNames: {
7
- months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
8
- month: 'space-y-4',
9
- caption: 'flex justify-center pt-1 relative items-center',
10
- caption_label: 'text-sm font-medium',
11
- nav: 'space-x-1 flex items-center',
12
- nav_button: cn(variantStyles.outline, 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100'),
13
- nav_button_previous: 'absolute left-1',
14
- nav_button_next: 'absolute right-1',
15
- table: 'w-full border-collapse space-y-1',
16
- head_row: 'flex',
17
- head_cell: 'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
18
- row: 'flex w-full mt-2',
19
- cell: cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md', props.mode === 'range'
20
- ? '[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'
21
- : '[&:has([aria-selected])]:rounded-md'),
22
- day: cn(variantStyles.ghost, 'h-8 w-8 p-0 font-normal aria-selected:opacity-100'),
23
- day_range_start: 'day-range-start',
24
- day_range_end: 'day-range-end',
25
- day_selected: 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
26
- day_today: 'bg-accent text-accent-foreground',
27
- day_outside: 'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30',
28
- day_disabled: 'text-muted-foreground opacity-50',
29
- day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground',
30
- day_hidden: 'invisible',
31
- ...classNames,
32
- }, ...props }));
6
+ return (_jsx("div", { style: {
7
+ // Provide fallback CSS variables for colors
8
+ ['--primary']: 'var(--primary, hsl(305 38% 54%))',
9
+ ['--primary-foreground']: 'var(--primary-foreground, hsl(0 0% 100%))',
10
+ ['--accent']: 'var(--accent, hsl(305 38% 94%))',
11
+ ['--accent-foreground']: 'var(--accent-foreground, hsl(305 38% 20%))',
12
+ ['--muted-foreground']: 'var(--muted-foreground, hsl(0 0% 45%))',
13
+ }, children: _jsx(DayPicker, { showOutsideDays: showOutsideDays, className: cn('p-3', className), classNames: {
14
+ months: 'flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0',
15
+ month: 'space-y-4',
16
+ caption: 'flex justify-center pt-1 relative items-center',
17
+ caption_label: 'text-sm font-medium',
18
+ nav: 'space-x-1 flex items-center',
19
+ nav_button: cn(variantStyles.outline, 'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100'),
20
+ nav_button_previous: 'absolute left-1',
21
+ nav_button_next: 'absolute right-1',
22
+ table: 'w-full border-collapse space-y-1',
23
+ head_row: 'flex',
24
+ head_cell: 'text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]',
25
+ row: 'flex w-full mt-2',
26
+ cell: cn('relative p-0 text-center text-sm focus-within:relative focus-within:z-20', props.mode === 'range'
27
+ ? '[&:has([aria-selected].day-range-middle)]:bg-accent [&:has([aria-selected].day-range-start)]:bg-accent [&:has([aria-selected].day-range-end)]:bg-accent [&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md'
28
+ : '[&:has([aria-selected])]:rounded-md [&:has([aria-selected])]:bg-accent'),
29
+ day: cn(variantStyles.ghost, 'h-8 w-8 p-0 font-normal aria-selected:opacity-100'),
30
+ day_range_start: 'day-range-start',
31
+ day_range_end: 'day-range-end',
32
+ day_selected: 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground',
33
+ day_today: 'bg-accent text-accent-foreground',
34
+ day_outside: 'day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30',
35
+ day_disabled: 'text-muted-foreground opacity-50',
36
+ day_range_middle: 'aria-selected:bg-accent aria-selected:text-accent-foreground rounded-none',
37
+ day_hidden: 'invisible',
38
+ ...classNames,
39
+ }, ...props }) }));
33
40
  };
34
41
  Calendar.displayName = 'Calendar';
35
42
  export default Calendar;
@@ -63,8 +63,8 @@ export const defaultDatePresets = [
63
63
  label: 'Custom Range',
64
64
  value: 'custom',
65
65
  getRange: () => ({
66
- from: startOfDay(subDays(new Date(), 6)),
67
- to: endOfDay(new Date()),
66
+ from: undefined,
67
+ to: undefined,
68
68
  }),
69
69
  },
70
70
  ];
@@ -89,7 +89,7 @@ export const defaultDatePresets = [
89
89
  * />
90
90
  * ```
91
91
  */
92
- const DateRangePickerWithPresets = ({ value, onChange, presets = defaultDatePresets, selectedPreset = 'last_7_days', placeholder = 'Select date range', minDate, maxDate = new Date(), numberOfMonths = 2, className, showClearButton = true, dateFormat = 'MM/dd/yyyy', disabled = false, }) => {
92
+ const DateRangePickerWithPresets = ({ value, onChange, presets = defaultDatePresets, selectedPreset = 'last_7_days', placeholder = 'Select date range', minDate, maxDate, numberOfMonths = 2, className, showClearButton = true, dateFormat = 'MM/dd/yyyy', disabled = false, }) => {
93
93
  const [isOpen, setIsOpen] = useState(false);
94
94
  const [tempRange, setTempRange] = useState(value);
95
95
  const [tempPreset, setTempPreset] = useState(selectedPreset);
@@ -111,11 +111,19 @@ const DateRangePickerWithPresets = ({ value, onChange, presets = defaultDatePres
111
111
  }, [value, dateFormat, placeholder]);
112
112
  // Handle preset selection
113
113
  const handlePresetSelect = (preset) => {
114
- const range = preset.getRange();
115
- setTempRange(range);
116
- setTempPreset(preset.value);
117
- // For non-custom presets, immediately apply and close
118
- if (preset.value !== 'custom') {
114
+ // For custom preset, preserve current selection or clear it
115
+ if (preset.value === 'custom') {
116
+ setTempPreset('custom');
117
+ // Keep current tempRange if it exists, otherwise undefined
118
+ if (!tempRange?.from && !tempRange?.to) {
119
+ setTempRange(undefined);
120
+ }
121
+ }
122
+ else {
123
+ // For other presets, apply immediately
124
+ const range = preset.getRange();
125
+ setTempRange(range);
126
+ setTempPreset(preset.value);
119
127
  onChange?.(range, preset.value);
120
128
  setIsOpen(false);
121
129
  }
@@ -141,8 +149,17 @@ const DateRangePickerWithPresets = ({ value, onChange, presets = defaultDatePres
141
149
  e.stopPropagation();
142
150
  onChange?.(undefined, undefined);
143
151
  };
144
- return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", disabled: disabled, className: cn('w-auto justify-start text-left font-normal', !value && 'text-muted-foreground', className), children: [_jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: displayText }), showClearButton && value?.from && (_jsx(X, { className: "ml-2 h-4 w-4 opacity-50 hover:opacity-100 cursor-pointer", onClick: handleClear }))] }) }), _jsx(PopoverContent, { className: "w-auto p-0 bg-background border border-border shadow-lg", align: "start", sideOffset: 8, children: _jsxs("div", { className: "flex", children: [_jsx("div", { className: "border-r border-border p-2 min-w-[140px] bg-background", children: _jsx("div", { className: "flex flex-col gap-1", children: presets.map((preset) => (_jsx("button", { type: "button", onClick: () => handlePresetSelect(preset), className: cn('text-left px-3 py-2 text-sm rounded-md transition-colors', 'hover:bg-accent hover:text-accent-foreground', tempPreset === preset.value &&
145
- 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground'), children: preset.label }, preset.value))) }) }), tempPreset === 'custom' && (_jsxs("div", { className: "p-3 bg-background", children: [_jsx(Calendar, { mode: "range", defaultMonth: tempRange?.from, selected: tempRange, onSelect: handleCalendarSelect, numberOfMonths: numberOfMonths, disabled: (date) => {
152
+ return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { variant: "outline", disabled: disabled, className: cn('w-auto justify-start text-left font-normal', !value && 'text-muted-foreground', className), children: [_jsx(CalendarIcon, { className: "mr-2 h-4 w-4" }), _jsx("span", { children: displayText }), showClearButton && value?.from && (_jsx(X, { className: "ml-2 h-4 w-4 opacity-50 hover:opacity-100 cursor-pointer", onClick: handleClear }))] }) }), _jsx(PopoverContent, { className: "w-auto p-0 bg-background border border-border shadow-lg", align: "start", sideOffset: 8, children: _jsxs("div", { className: "flex", style: {
153
+ // Provide fallback CSS variables for colors
154
+ ['--primary']: 'var(--primary, hsl(305 38% 54%))',
155
+ ['--primary-foreground']: 'var(--primary-foreground, hsl(0 0% 100%))',
156
+ ['--accent']: 'var(--accent, hsl(305 38% 94%))',
157
+ ['--accent-foreground']: 'var(--accent-foreground, hsl(305 38% 20%))',
158
+ ['--background']: 'var(--background, hsl(0 0% 100%))',
159
+ ['--border']: 'var(--border, hsl(0 0% 90%))',
160
+ ['--muted-foreground']: 'var(--muted-foreground, hsl(0 0% 45%))',
161
+ }, children: [_jsx("div", { className: "border-r border-border p-2 min-w-[140px] bg-background", children: _jsx("div", { className: "flex flex-col gap-1", children: presets.map((preset) => (_jsx("button", { type: "button", onClick: () => handlePresetSelect(preset), className: cn('text-left px-3 py-2 text-sm rounded-md transition-colors', 'hover:bg-accent hover:text-accent-foreground', tempPreset === preset.value &&
162
+ 'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground'), children: preset.label }, preset.value))) }) }), tempPreset === 'custom' && (_jsxs("div", { className: "p-3 bg-background", children: [_jsx(Calendar, { mode: "range", defaultMonth: tempRange?.from || new Date(), selected: tempRange, onSelect: handleCalendarSelect, numberOfMonths: numberOfMonths, disabled: (date) => {
146
163
  if (minDate && date < minDate)
147
164
  return true;
148
165
  if (maxDate && date > maxDate)
@@ -1,14 +1,13 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Input, MultiSelect, Select } from '@mantine/core';
3
- import { IconCalendar, IconSearch } from '@tabler/icons-react';
4
- import { format } from 'date-fns';
3
+ import { IconSearch } from '@tabler/icons-react';
4
+ import { endOfDay, startOfDay } from 'date-fns';
5
5
  import React from 'react';
6
6
  import { isDefaultFilterValue } from '../../shared/utils/filterUtils';
7
7
  import Button from './Button';
8
8
  import DatePicker from './DatePicker';
9
+ import DateRangePickerWithPresets from './DateRangePickerWithPresets';
9
10
  import FilterWrapper from './FilterWrapper';
10
- import { Popover, PopoverContent, PopoverTrigger } from './Popover';
11
- import RangeDatePicker from './RangeDatePicker';
12
11
  const sharedStyles = {
13
12
  input: {
14
13
  borderRadius: '6px',
@@ -84,28 +83,24 @@ const FilterComponent = ({ filters, selectedFilters, showApplyFilterButton = tru
84
83
  const endDateValue = rangeKeys ? selectedFilters[rangeKeys.end] : undefined;
85
84
  const startDate = parseDateValue(startDateValue);
86
85
  const endDate = parseDateValue(endDateValue);
87
- const displayValue = startDate && endDate
88
- ? `${format(startDate, 'dd MMM yyyy')} - ${format(endDate, 'dd MMM yyyy')}`
89
- : (filter.placeholder ?? 'Select date range');
90
- const applyRange = (start, end) => {
86
+ const dateRange = startDate && endDate
87
+ ? { from: startDate, to: endDate }
88
+ : startDate
89
+ ? { from: startDate, to: startDate }
90
+ : undefined;
91
+ const handleRangeChange = (range) => {
91
92
  if (!rangeKeys)
92
93
  return;
93
- handleFilterChange(rangeKeys.start, start);
94
- handleFilterChange(rangeKeys.end, end);
94
+ if (range?.from) {
95
+ handleFilterChange(rangeKeys.start, startOfDay(range.from));
96
+ handleFilterChange(rangeKeys.end, range.to ? endOfDay(range.to) : endOfDay(range.from));
97
+ }
98
+ else {
99
+ handleFilterChange(rangeKeys.start, null);
100
+ handleFilterChange(rangeKeys.end, null);
101
+ }
95
102
  };
96
- const rangeSelection = {
97
- startDate: startDate ?? new Date(),
98
- endDate: endDate ?? startDate ?? new Date(),
99
- key: name,
100
- };
101
- return (_jsxs(Popover, { open: activeRangePicker === name, onOpenChange: (open) => setActiveRangePicker(open ? name : null), children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: "flex w-full items-center justify-between rounded-md border border-gray-300 bg-white px-3 py-2 text-left text-sm text-gray-700 shadow-sm transition hover:border-gray-400 focus:outline-none focus:ring-2 focus:ring-primary-500", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(IconCalendar, { size: 16, className: "text-gray-500" }), _jsx("span", { className: !startDate || !endDate ? 'text-gray-400' : '', children: displayValue })] }) }) }), _jsx(PopoverContent, { align: "start", className: "w-auto border border-gray-200 bg-white p-0 shadow-2xl", children: _jsxs("div", { className: "p-4", children: [_jsx(RangeDatePicker, { dateRange: rangeSelection, rangeKey: name, onChange: (updatedRange) => {
102
- if (updatedRange.startDate) {
103
- applyRange(updatedRange.startDate, updatedRange.endDate ?? updatedRange.startDate);
104
- }
105
- }, months: 2, showPreview: false }), _jsxs("div", { className: "flex justify-end gap-2 pt-3", children: [_jsx(Button, { variant: "outline-primary", type: "button", onClick: () => {
106
- applyRange(null, null);
107
- setActiveRangePicker(null);
108
- }, className: "h-9 px-3", children: "Clear" }), _jsx(Button, { variant: "primary", type: "button", onClick: () => setActiveRangePicker(null), className: "h-9 px-4", children: "Done" })] })] }) })] }));
103
+ return (_jsx(DateRangePickerWithPresets, { value: dateRange, onChange: handleRangeChange, placeholder: filter.placeholder ?? 'Select date range', showClearButton: true, className: "w-full" }));
109
104
  }
110
105
  if (type === 'date') {
111
106
  return (_jsx(DatePicker, { value: value || null, onChange: (date) => handleFilterChange(name, date), placeholder: filter.placeholder ?? `Select ${name}` }));
package/lib/styles.css CHANGED
@@ -3816,11 +3816,6 @@ input[type="range"]::-ms-fill-lower {
3816
3816
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
3817
3817
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
3818
3818
  }
3819
- .shadow-2xl {
3820
- --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
3821
- --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
3822
- box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
3823
- }
3824
3819
  .shadow-lg {
3825
3820
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
3826
3821
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
@@ -6784,12 +6779,14 @@ input[type="range"]::-ms-fill-lower {
6784
6779
  border-top-right-radius: 0.375rem;
6785
6780
  border-bottom-right-radius: 0.375rem;
6786
6781
  }
6787
- .\[\&\:has\(\[aria-selected\]\.day-outside\)\]\:bg-accent\/50:has([aria-selected].day-outside) {
6788
- background-color: hsl(var(--accent) / 0.5);
6782
+ .\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:bg-accent:has([aria-selected].day-range-end) {
6783
+ background-color: hsl(var(--accent));
6789
6784
  }
6790
- .\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:rounded-r-md:has([aria-selected].day-range-end) {
6791
- border-top-right-radius: 0.375rem;
6792
- border-bottom-right-radius: 0.375rem;
6785
+ .\[\&\:has\(\[aria-selected\]\.day-range-middle\)\]\:bg-accent:has([aria-selected].day-range-middle) {
6786
+ background-color: hsl(var(--accent));
6787
+ }
6788
+ .\[\&\:has\(\[aria-selected\]\.day-range-start\)\]\:bg-accent:has([aria-selected].day-range-start) {
6789
+ background-color: hsl(var(--accent));
6793
6790
  }
6794
6791
  .\[\&\>\*\]\:pointer-events-none>* {
6795
6792
  pointer-events: none;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pagamio/frontend-commons-lib",
3
3
  "description": "Pagamio library for Frontend reusable components like the form engine and table container",
4
- "version": "0.8.238",
4
+ "version": "0.8.239",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "provenance": false