@via-profit/ui-kit 0.1.8 → 0.2.1-alpha.1

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.
@@ -38,19 +38,19 @@ export interface AccordionOverrides {
38
38
  /**
39
39
  * Accordion container component
40
40
  */
41
- readonly Container?: React.ForwardRefExoticComponent<AccordionContainerProps & React.RefAttributes<HTMLDivElement>>;
41
+ readonly Container?: React.ComponentType<AccordionContainerProps & React.RefAttributes<HTMLDivElement>>;
42
42
  /**
43
43
  * Accordion header component
44
44
  */
45
- readonly Header?: React.ForwardRefExoticComponent<AccordionHeaderProps & React.RefAttributes<HTMLDivElement>>;
45
+ readonly Header?: React.ComponentType<AccordionHeaderProps & React.RefAttributes<HTMLDivElement>>;
46
46
  /**
47
47
  * Accordion content component
48
48
  */
49
- readonly Content?: React.ForwardRefExoticComponent<AccordionContentProps & React.RefAttributes<HTMLDivElement>>;
49
+ readonly Content?: React.ComponentType<AccordionContentProps & React.RefAttributes<HTMLDivElement>>;
50
50
  /**
51
51
  * Accordion footer component
52
52
  */
53
- readonly Actions?: React.ForwardRefExoticComponent<AccordionActionsProps & React.RefAttributes<HTMLDivElement>>;
53
+ readonly Actions?: React.ComponentType<AccordionActionsProps & React.RefAttributes<HTMLDivElement>>;
54
54
  }
55
55
  declare const _default: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLDivElement> & {
56
56
  readonly children: React.ReactNode | React.ReactNode[];
@@ -110,7 +110,7 @@ export interface AutocompleteOverrides {
110
110
  /**
111
111
  * Element wrapper
112
112
  */
113
- readonly TextField?: React.ForwardRefExoticComponent<AutocompleteTextFieldProps & React.RefAttributes<HTMLDivElement>>;
113
+ readonly TextField?: React.ComponentType<AutocompleteTextFieldProps & React.RefAttributes<HTMLDivElement>>;
114
114
  }
115
115
  export type Children<T> = (data: {
116
116
  item: T;
@@ -46,7 +46,7 @@ const context_1 = __importStar(require("./context"));
46
46
  const IconClear_1 = __importDefault(require("./IconClear"));
47
47
  const ClickOutside_1 = require("../ClickOutside");
48
48
  const Autocomplete = react_1.default.forwardRef((props, ref) => {
49
- const { items, value, multiple, isOpen = false, isLoading = false, clearOnBlur = true, anchorPos = 'auto-start-end', openOnFocus = true, requiredAsterisk, startIcon, fullWidth, placeholder, label, error, errorText, inputRef, filterItems, children, onChange, selectedItemToString, clearable = true, onInputChange, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides } = props, nativeInputProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "clearOnBlur", "anchorPos", "openOnFocus", "requiredAsterisk", "startIcon", "fullWidth", "placeholder", "label", "error", "errorText", "inputRef", "filterItems", "children", "onChange", "selectedItemToString", "clearable", "onInputChange", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides"]);
49
+ const { items, value, multiple, isOpen = false, isLoading = false, clearOnBlur = true, anchorPos = 'bottom', openOnFocus = true, requiredAsterisk, startIcon, fullWidth, placeholder, label, error, errorText, inputRef, filterItems, children, onChange, selectedItemToString, clearable = true, onInputChange, getOptionSelected, onRequestOpen = () => undefined, onRequestClose = () => undefined, overrides } = props, nativeInputProps = __rest(props, ["items", "value", "multiple", "isOpen", "isLoading", "clearOnBlur", "anchorPos", "openOnFocus", "requiredAsterisk", "startIcon", "fullWidth", "placeholder", "label", "error", "errorText", "inputRef", "filterItems", "children", "onChange", "selectedItemToString", "clearable", "onInputChange", "getOptionSelected", "onRequestOpen", "onRequestClose", "overrides"]);
50
50
  const menuRef = react_1.default.useRef(null);
51
51
  const fieldInputRef = react_1.default.useRef(null);
52
52
  const isFocusedRef = react_1.default.useRef(false);
@@ -55,19 +55,19 @@ export interface AvatarBaseOverrides {
55
55
  /**
56
56
  * Element container
57
57
  */
58
- readonly Container?: React.ForwardRefExoticComponent<AvatarContainerProps & React.RefAttributes<HTMLSpanElement>>;
58
+ readonly Container?: React.ComponentType<AvatarContainerProps & React.RefAttributes<HTMLSpanElement>>;
59
59
  /**
60
60
  * icon wrapper
61
61
  */
62
- readonly IconWrapper?: React.ForwardRefExoticComponent<AvatarIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
62
+ readonly IconWrapper?: React.ComponentType<AvatarIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
63
63
  /**
64
64
  * text wrapper
65
65
  */
66
- readonly TextWrapper?: React.ForwardRefExoticComponent<AvatarTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
66
+ readonly TextWrapper?: React.ComponentType<AvatarTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
67
67
  /**
68
68
  * picture tag
69
69
  */
70
- readonly Picture?: React.ForwardRefExoticComponent<AvatarPictureProps & React.RefAttributes<HTMLPictureElement>>;
70
+ readonly Picture?: React.ComponentType<AvatarPictureProps & React.RefAttributes<HTMLPictureElement>>;
71
71
  }
72
72
  declare const _default: React.ForwardRefExoticComponent<AvatarBaseProps & React.RefAttributes<HTMLSpanElement>>;
73
73
  export default _default;
@@ -36,19 +36,19 @@ export interface BadgeBaseOverrides {
36
36
  /**
37
37
  * Element container
38
38
  */
39
- readonly Container?: React.ForwardRefExoticComponent<BadgeContainerProps & React.RefAttributes<HTMLSpanElement>>;
39
+ readonly Container?: React.ComponentType<BadgeContainerProps & React.RefAttributes<HTMLSpanElement>>;
40
40
  /**
41
41
  * icon wrapper
42
42
  */
43
- readonly IconWrapper?: React.ForwardRefExoticComponent<BadgeIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
43
+ readonly IconWrapper?: React.ComponentType<BadgeIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
44
44
  /**
45
45
  * text wrapper
46
46
  */
47
- readonly TextWrapper?: React.ForwardRefExoticComponent<BadgeTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
47
+ readonly TextWrapper?: React.ComponentType<BadgeTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
48
48
  /**
49
49
  * Icon delete
50
50
  */
51
- readonly ButtonDelete?: React.ForwardRefExoticComponent<BadgeDeleteButtonProps & React.RefAttributes<HTMLButtonElement>>;
51
+ readonly ButtonDelete?: React.ComponentType<BadgeDeleteButtonProps & React.RefAttributes<HTMLButtonElement>>;
52
52
  }
53
53
  declare const _default: React.ForwardRefExoticComponent<BadgeBaseProps & React.RefAttributes<HTMLSpanElement>>;
54
54
  export default _default;
@@ -48,15 +48,15 @@ export interface ButtonBaseOverrides {
48
48
  /**
49
49
  * Element container
50
50
  */
51
- readonly Container?: React.ForwardRefExoticComponent<ButtonContainerProps & React.RefAttributes<HTMLButtonElement>>;
51
+ readonly Container?: React.ComponentType<ButtonContainerProps & React.RefAttributes<HTMLButtonElement>>;
52
52
  /**
53
53
  * icon wrapper
54
54
  */
55
- readonly IconWrapper?: React.ForwardRefExoticComponent<ButtonIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
55
+ readonly IconWrapper?: React.ComponentType<ButtonIconWrapperProps & React.RefAttributes<HTMLSpanElement>>;
56
56
  /**
57
57
  * text wrapper
58
58
  */
59
- readonly TextWrapper?: React.ForwardRefExoticComponent<ButtonTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
59
+ readonly TextWrapper?: React.ComponentType<ButtonTextWrapperProps & React.RefAttributes<HTMLSpanElement>>;
60
60
  }
61
61
  declare const _default: React.ForwardRefExoticComponent<ButtonBaseProps & React.RefAttributes<HTMLButtonElement>>;
62
62
  export default _default;
@@ -29,14 +29,28 @@ const Btn = (0, styled_1.default)(Button_1.default) `
29
29
  min-width: 0;
30
30
  outline: none;
31
31
  position: relative;
32
- border-radius: ${({ theme, $fill }) => ($fill ? 0 : theme.shape.radiusFactor * 3)}em;
33
- ${({ $fill, theme }) => $fill &&
32
+ border-radius: ${({ theme }) => theme.shape.radiusFactor * 3}em;
33
+ ${({ $fill, theme, $isSelected }) => $fill &&
34
+ !$isSelected &&
34
35
  (0, react_2.css) `
35
- background-color: ${theme.color.accentPrimary.alpha(0.2).toString()};
36
+ background-color: none;
37
+ position: relative;
38
+
39
+ &:before {
40
+ position: absolute;
41
+ border-radius: ${theme.shape.radiusFactor * 0.8}em;
42
+ inset: 0.6em;
43
+ content: '';
44
+ background-color: ${theme.color.accentPrimary.alpha(0.9).toString()};
45
+ }
46
+ & > span {
47
+ position: relative;
48
+ color: ${theme.color.accentPrimaryContrast.toString()};
49
+ }
36
50
  `};
37
51
  `;
38
52
  const CalendarCell = (props, ref) => {
39
53
  const { isToday, children, isSelected, isDisabled, accentColor, fill } = props, restProps = __rest(props, ["isToday", "children", "isSelected", "isDisabled", "accentColor", "fill"]);
40
- return (react_1.default.createElement(Btn, Object.assign({ iconOnly: true, type: "button", "$fill": fill, variant: isSelected ? 'standard' : isToday ? 'outlined' : 'plain', color: isSelected || isToday ? accentColor : 'default', tabIndex: isDisabled ? -1 : restProps.tabIndex, disabled: isDisabled }, restProps, { ref: ref }), children));
54
+ return (react_1.default.createElement(Btn, Object.assign({ iconOnly: true, type: "button", "$fill": fill, "$isSelected": isSelected, variant: isSelected ? 'standard' : isToday ? 'outlined' : 'plain', color: isSelected || isToday ? accentColor : 'default', tabIndex: isDisabled ? -1 : restProps.tabIndex, disabled: isDisabled }, restProps, { ref: ref }), children));
41
55
  };
42
56
  exports.default = react_1.default.forwardRef(CalendarCell);
@@ -30,11 +30,6 @@ const Btn = (0, styled_1.default)(Button_1.default) `
30
30
  const CalendarMonthCell = (props, ref) => {
31
31
  const { children, isSelected, accentColor } = props, restProps = __rest(props, ["children", "isSelected", "accentColor"]);
32
32
  const myRef = react_1.default.useRef(null);
33
- react_1.default.useEffect(() => {
34
- if (isSelected && myRef.current) {
35
- myRef.current.scrollIntoView({ behavior: 'instant' });
36
- }
37
- }, [isSelected]);
38
33
  return (react_1.default.createElement(Btn, Object.assign({}, restProps, { type: "button", variant: isSelected ? 'standard' : 'plain', color: isSelected ? accentColor : 'default', ref: el => {
39
34
  if (typeof ref === 'function') {
40
35
  ref(el);
@@ -30,11 +30,11 @@ const Btn = (0, styled_1.default)(Button_1.default) `
30
30
  const CalendarYearCell = (props, ref) => {
31
31
  const { children, isSelected, accentColor } = props, restProps = __rest(props, ["children", "isSelected", "accentColor"]);
32
32
  const myRef = react_1.default.useRef(null);
33
- react_1.default.useEffect(() => {
34
- if (isSelected && myRef.current) {
35
- myRef.current.scrollIntoView({ behavior: 'instant' });
36
- }
37
- }, [isSelected]);
33
+ // React.useEffect(() => {
34
+ // if (isSelected && myRef.current) {
35
+ // myRef.current.scrollIntoView({ behavior: 'instant' });
36
+ // }
37
+ // }, [isSelected]);
38
38
  return (react_1.default.createElement(Btn, Object.assign({}, restProps, { type: "button", variant: isSelected ? 'standard' : 'plain', color: isSelected ? accentColor : 'default', ref: el => {
39
39
  if (typeof ref === 'function') {
40
40
  ref(el);
@@ -106,7 +106,7 @@ export type CalendarProps<Range extends boolean | undefined = undefined> = {
106
106
  /**
107
107
  * Label for the Today button. If label passed, then button will be rendered
108
108
  */
109
- readonly toodayButtonLabel?: string;
109
+ readonly todayButtonLabel?: string;
110
110
  /**
111
111
  * Heading
112
112
  */
@@ -120,6 +120,10 @@ export type CalendarProps<Range extends boolean | undefined = undefined> = {
120
120
  * **Default:** `days`
121
121
  */
122
122
  readonly initialView?: CalendarView;
123
+ /**
124
+ * Posibility calendar views list
125
+ */
126
+ readonly views?: readonly CalendarView[];
123
127
  /**
124
128
  * Custom footer elements
125
129
  */
@@ -133,83 +137,83 @@ export interface CalendarOverrides {
133
137
  /**
134
138
  * Element container
135
139
  */
136
- readonly Body?: React.ForwardRefExoticComponent<CalendarBodyProps & React.RefAttributes<HTMLDivElement>>;
140
+ readonly Body?: React.ComponentType<CalendarBodyProps & React.RefAttributes<HTMLDivElement>>;
137
141
  /**
138
142
  * Day element
139
143
  */
140
- readonly Cell?: React.ForwardRefExoticComponent<CalendarCellProps & React.RefAttributes<HTMLButtonElement>>;
144
+ readonly Cell?: React.ComponentType<CalendarCellProps & React.RefAttributes<HTMLButtonElement>>;
141
145
  /**
142
146
  * Empty cell element
143
147
  */
144
- readonly EmptyCell?: React.ForwardRefExoticComponent<CalendarEmptyCellProps & React.RefAttributes<HTMLButtonElement>>;
148
+ readonly EmptyCell?: React.ComponentType<CalendarEmptyCellProps & React.RefAttributes<HTMLButtonElement>>;
145
149
  /**
146
150
  * Common container element
147
151
  */
148
- readonly Paper?: React.ForwardRefExoticComponent<CalendarPaperProps & React.RefAttributes<HTMLDivElement>>;
152
+ readonly Paper?: React.ComponentType<CalendarPaperProps & React.RefAttributes<HTMLDivElement>>;
149
153
  /**
150
154
  * Header wrapper element
151
155
  */
152
- readonly Header?: React.ForwardRefExoticComponent<CalendarHeaderProps & React.RefAttributes<HTMLDivElement>>;
156
+ readonly Header?: React.ComponentType<CalendarHeaderProps & React.RefAttributes<HTMLDivElement>>;
153
157
  /**
154
158
  * Week row container element
155
159
  */
156
- readonly WeekRow?: React.ForwardRefExoticComponent<CalendarWeekRowProps & React.RefAttributes<HTMLDivElement>>;
160
+ readonly WeekRow?: React.ComponentType<CalendarWeekRowProps & React.RefAttributes<HTMLDivElement>>;
157
161
  /**
158
162
  * Days wrapper element
159
163
  */
160
- readonly DateContainer?: React.ForwardRefExoticComponent<CalendarDateContainerProps & React.RefAttributes<HTMLDivElement>>;
164
+ readonly DateContainer?: React.ComponentType<CalendarDateContainerProps & React.RefAttributes<HTMLDivElement>>;
161
165
  /**
162
166
  * Toolbar wrapper element
163
167
  */
164
- readonly Toolbar?: React.ForwardRefExoticComponent<CalendarToolbarProps & React.RefAttributes<HTMLDivElement>>;
168
+ readonly Toolbar?: React.ComponentType<CalendarToolbarProps & React.RefAttributes<HTMLDivElement>>;
165
169
  /**
166
170
  * Years list element (year view)
167
171
  */
168
- readonly YearsSelector?: React.ForwardRefExoticComponent<CalendarYearsSelectorProps & React.RefAttributes<HTMLDivElement>>;
172
+ readonly YearsSelector?: React.ComponentType<CalendarYearsSelectorProps & React.RefAttributes<HTMLDivElement>>;
169
173
  /**
170
174
  * Monthes list element (month view)
171
175
  */
172
- readonly MonthsSelector?: React.ForwardRefExoticComponent<CalendarMonthsSelectorProps & React.RefAttributes<HTMLDivElement>>;
176
+ readonly MonthsSelector?: React.ComponentType<CalendarMonthsSelectorProps & React.RefAttributes<HTMLDivElement>>;
173
177
  /**
174
178
  * Month cell element in monthes list
175
179
  */
176
- readonly MonthCell?: React.ForwardRefExoticComponent<CalendarMonthCellProps & React.RefAttributes<HTMLButtonElement>>;
180
+ readonly MonthCell?: React.ComponentType<CalendarMonthCellProps & React.RefAttributes<HTMLButtonElement>>;
177
181
  /**
178
182
  * Year cell element in years list
179
183
  */
180
- readonly YearCell?: React.ForwardRefExoticComponent<CalendarYearCellProps & React.RefAttributes<HTMLButtonElement>>;
184
+ readonly YearCell?: React.ComponentType<CalendarYearCellProps & React.RefAttributes<HTMLButtonElement>>;
181
185
  /**
182
186
  * Badge of the day cell element
183
187
  */
184
- readonly DayBadge?: React.ForwardRefExoticComponent<CalendarDayBadgeProps & React.RefAttributes<HTMLSpanElement>>;
188
+ readonly DayBadge?: React.ComponentType<CalendarDayBadgeProps & React.RefAttributes<HTMLSpanElement>>;
185
189
  /**
186
190
  * Footer container element
187
191
  */
188
- readonly Footer?: React.ForwardRefExoticComponent<CalendarFooterProps & React.RefAttributes<HTMLDivElement>>;
192
+ readonly Footer?: React.ComponentType<CalendarFooterProps & React.RefAttributes<HTMLDivElement>>;
189
193
  /**
190
194
  * Common button element
191
195
  */
192
- readonly ControlButton?: React.ForwardRefExoticComponent<CalendarControlButtonProps & React.RefAttributes<HTMLButtonElement>>;
196
+ readonly ControlButton?: React.ComponentType<CalendarControlButtonProps & React.RefAttributes<HTMLButtonElement>>;
193
197
  /**
194
198
  * Heading element
195
199
  */
196
- readonly Heading?: React.ForwardRefExoticComponent<CalendarHeadingProps & React.RefAttributes<HTMLDivElement>>;
200
+ readonly Heading?: React.ComponentType<CalendarHeadingProps & React.RefAttributes<HTMLDivElement>>;
197
201
  /**
198
202
  * Subheading element
199
203
  */
200
- readonly Subheading?: React.ForwardRefExoticComponent<CalendarSubheadingProps & React.RefAttributes<HTMLDivElement>>;
204
+ readonly Subheading?: React.ComponentType<CalendarSubheadingProps & React.RefAttributes<HTMLDivElement>>;
201
205
  /**
202
206
  * Prev icon element in prev month button
203
207
  */
204
- readonly IconPrev?: React.ForwardRefExoticComponent<CalendarIconPrevProps & React.RefAttributes<SVGElement>>;
208
+ readonly IconPrev?: React.ComponentType<CalendarIconPrevProps & React.RefAttributes<SVGElement>>;
205
209
  /**
206
210
  * Next icon element in next month button
207
211
  */
208
- readonly IconNext?: React.ForwardRefExoticComponent<CalendarIconNextProps & React.RefAttributes<SVGElement>>;
212
+ readonly IconNext?: React.ComponentType<CalendarIconNextProps & React.RefAttributes<SVGElement>>;
209
213
  /**
210
214
  * Weeks bar element
211
215
  */
212
- readonly WeekDaysBar?: React.ForwardRefExoticComponent<CalendarWeekDaysBarProps & React.RefAttributes<HTMLDivElement>>;
216
+ readonly WeekDaysBar?: React.ComponentType<CalendarWeekDaysBarProps & React.RefAttributes<HTMLDivElement>>;
213
217
  }
214
218
  export type CalendarBadge = {
215
219
  readonly date: Date;
package/Calendar/index.js CHANGED
@@ -43,7 +43,7 @@ const reducer_1 = require("./reducer");
43
43
  __exportStar(require("./use-calendar"), exports);
44
44
  __exportStar(require("./CalendarWeekDaysBar"), exports);
45
45
  const Calendar = (props) => {
46
- const { minDate = new Date(new Date().getFullYear() - 100, 0, 1, 0, 0, 0), maxDate = new Date(new Date().getFullYear() + 100, 0, 1, 0, 0, 0), weekStartDay = 'monday', locale = 'ru-RU', displayLeadingZero = false, onChange, badges = [], value, defaultValue, markToday, weekDayLabelFormat = 'short', accentColor = 'primary', prevMonthButtonTooltip, nextMonthButtonTooltip, changeMonthButtonTooltip, changeYearButtonTooltip, initialView = (0, reducer_1.createDefaultState)(false).calendarCurrentView, resetButtonLabel, toodayButtonLabel, heading, subheading, footer, overrides, range = false, } = props;
46
+ const { minDate = new Date(new Date().getFullYear() - 100, 0, 1, 0, 0, 0), maxDate = new Date(new Date().getFullYear() + 100, 0, 1, 0, 0, 0), weekStartDay = 'monday', locale = 'ru-RU', displayLeadingZero = false, onChange, badges = [], value, defaultValue, markToday, weekDayLabelFormat = 'short', accentColor = 'primary', prevMonthButtonTooltip, nextMonthButtonTooltip, changeMonthButtonTooltip, changeYearButtonTooltip, initialView, views, resetButtonLabel, todayButtonLabel, heading, subheading, footer, overrides, range = false, } = props;
47
47
  if (typeof value !== 'undefined' && typeof onChange === 'undefined') {
48
48
  throw new Error('You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange`.');
49
49
  }
@@ -78,8 +78,12 @@ const Calendar = (props) => {
78
78
  value: realValue,
79
79
  badges,
80
80
  initialView,
81
+ views,
81
82
  });
82
- const initialState = Object.assign(Object.assign({}, (0, reducer_1.createDefaultState)(range)), { calendarValue: realValue, calendarDate: Array.isArray(realValue) ? realValue[0] : realValue, calendarCurrentView: initialView });
83
+ const initialState = Object.assign(Object.assign({}, (0, reducer_1.createDefaultState)(range, {
84
+ initialView,
85
+ views,
86
+ })), { calendarValue: realValue, calendarDate: Array.isArray(realValue) ? realValue[0] : realValue });
83
87
  const [state, dispatch] = react_1.default.useReducer(reducer_1.reducer, initialState);
84
88
  const { isSameDay, getWeeks, getDayLabel, getMonthLabel, getYearLabel, getYearsRange, getMonthsRange, } = (0, use_calendar_1.useCalendar)({
85
89
  minDate,
@@ -113,52 +117,41 @@ const Calendar = (props) => {
113
117
  }
114
118
  }, [value, calendarValue, isSameDay, dispatch]);
115
119
  /**
116
- * Handle click on Day button
120
+ * Handles click on a day cell.
121
+ * Range selection follows a simple two‑click model:
122
+ * 1) First click sets the start date.
123
+ * 2) Second click sets the end date.
124
+ * If a full range is already selected, a new click starts a new range.
117
125
  */
118
126
  const handleCellDateClick = react_1.default.useCallback((selectedDate) => () => {
119
- if (typeof onChange === 'function') {
120
- if (range) {
121
- const [fromDate, toDate] = calendarValue;
122
- dispatch({
123
- type: 'setPartial',
124
- payload: { calendarDate: selectedDate },
125
- });
126
- if (selectedDate.getTime() >= toDate.getTime()) {
127
- onChange([fromDate, selectedDate]);
128
- return;
129
- }
130
- if (selectedDate.getTime() < fromDate.getTime()) {
131
- onChange([selectedDate, toDate]);
132
- return;
133
- }
134
- if (selectedDate.getTime() > fromDate.getTime() &&
135
- selectedDate.getTime() < toDate.getTime()) {
136
- const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
137
- const daysBetweenFromDate = Math.round(Math.abs((fromDate.getTime() - selectedDate.getTime()) / oneDay));
138
- const daysBetweenToDate = Math.round(Math.abs((toDate.getTime() - selectedDate.getTime()) / oneDay));
139
- if (daysBetweenToDate <= daysBetweenFromDate) {
140
- onChange([fromDate, selectedDate]);
141
- return;
142
- }
143
- if (daysBetweenToDate > daysBetweenFromDate) {
144
- onChange([selectedDate, toDate]);
145
- return;
146
- }
147
- }
148
- throw new Error('Oooops. I don`t know whats is it');
127
+ if (!onChange) {
128
+ return;
129
+ }
130
+ // Single-date mode
131
+ if (!range) {
132
+ onChange(selectedDate);
133
+ return;
134
+ }
135
+ const [from, to] = calendarValue;
136
+ // No range selected yet → first click
137
+ if (!from && !to) {
138
+ onChange([selectedDate, selectedDate]);
139
+ return;
140
+ }
141
+ // Only start date selected → second click
142
+ if (from && (!to || from.getTime() === to.getTime())) {
143
+ if (selectedDate < from) {
144
+ // User clicked before the start → swap
145
+ onChange([selectedDate, from]);
149
146
  }
150
147
  else {
151
- onChange(selectedDate);
148
+ // Normal forward range
149
+ onChange([from, selectedDate]);
152
150
  }
151
+ return;
153
152
  }
154
- if (!calendarValue) {
155
- dispatch({
156
- type: 'setPartial',
157
- payload: {
158
- calendarValue: selectedDate,
159
- },
160
- });
161
- }
153
+ // Full range already selected → start a new range
154
+ onChange([selectedDate, selectedDate]);
162
155
  }, [onChange, calendarValue, range]);
163
156
  /**
164
157
  * Handle of click on year item
@@ -171,16 +164,18 @@ const Calendar = (props) => {
171
164
  newDate.setHours(0);
172
165
  newDate.setMinutes(0);
173
166
  newDate.setMilliseconds(0);
174
- if (calendarDate.getFullYear() !== newDate.getFullYear()) {
175
- dispatch({
176
- type: 'setPartial',
177
- payload: {
178
- calendarDate: newDate,
179
- calendarCurrentView: 'days',
180
- },
181
- });
167
+ const nextView = calendarViewVariants.includes('days') ? 'days' : undefined;
168
+ dispatch({
169
+ type: 'setPartial',
170
+ payload: {
171
+ calendarDate: newDate,
172
+ calendarCurrentView: nextView !== null && nextView !== void 0 ? nextView : calendarCurrentView,
173
+ },
174
+ });
175
+ if (!nextView && typeof onChange === 'function') {
176
+ handleCellDateClick(newDate)();
182
177
  }
183
- }, [calendarDate]);
178
+ }, [calendarCurrentView, calendarDate, calendarViewVariants, handleCellDateClick, onChange]);
184
179
  /**
185
180
  * Handle of click on month item
186
181
  */
@@ -191,27 +186,32 @@ const Calendar = (props) => {
191
186
  newDate.setHours(0);
192
187
  newDate.setMinutes(0);
193
188
  newDate.setMilliseconds(0);
194
- if (calendarDate.getMonth() !== newDate.getMonth()) {
195
- dispatch({
196
- type: 'setPartial',
197
- payload: {
198
- calendarDate: newDate,
199
- calendarCurrentView: 'days',
200
- },
201
- });
189
+ const nextView = calendarViewVariants.includes('days') ? 'days' : undefined;
190
+ dispatch({
191
+ type: 'setPartial',
192
+ payload: {
193
+ calendarDate: newDate,
194
+ calendarCurrentView: nextView !== null && nextView !== void 0 ? nextView : calendarCurrentView,
195
+ },
196
+ });
197
+ if (!nextView && typeof onChange === 'function') {
198
+ handleCellDateClick(newDate)();
202
199
  }
203
- }, [calendarDate]);
200
+ }, [calendarDate, calendarViewVariants, handleCellDateClick, onChange, calendarCurrentView]);
204
201
  /**
205
202
  * Manual view changing
206
203
  */
207
204
  const handleChangeView = react_1.default.useCallback((selectedView) => () => {
205
+ if (!calendarViewVariants.includes(selectedView)) {
206
+ return;
207
+ }
208
208
  dispatch({
209
209
  type: 'setPartial',
210
210
  payload: {
211
211
  calendarCurrentView: selectedView,
212
212
  },
213
213
  });
214
- }, []);
214
+ }, [calendarViewVariants]);
215
215
  /**
216
216
  * Handle click on «Reset» button
217
217
  */
@@ -244,6 +244,17 @@ const Calendar = (props) => {
244
244
  },
245
245
  });
246
246
  }, []);
247
+ const weeks = react_1.default.useMemo(() => (calendarCurrentView === 'days' ? getWeeks(calendarDate) : []), [calendarCurrentView, calendarDate, getWeeks]);
248
+ const yearsRange = react_1.default.useMemo(() => (calendarCurrentView === 'years' ? getYearsRange(minDate, maxDate) : []), [calendarCurrentView, minDate, maxDate, getYearsRange]);
249
+ const monthsRange = react_1.default.useMemo(() => (calendarCurrentView === 'months' ? getMonthsRange(minDate, maxDate) : []), [calendarCurrentView, minDate, maxDate, getMonthsRange]);
250
+ const normalizedRange = react_1.default.useMemo(() => {
251
+ const [from, to] = Array.isArray(calendarValue)
252
+ ? calendarValue[0].getTime() <= calendarValue[1].getTime()
253
+ ? calendarValue
254
+ : [calendarValue[1], calendarValue[0]]
255
+ : [calendarValue, calendarValue];
256
+ return [from, to];
257
+ }, [calendarValue]);
247
258
  return (react_1.default.createElement(overridesMap.Paper, null,
248
259
  react_1.default.createElement(overridesMap.Header, null,
249
260
  typeof heading !== 'undefined' && react_1.default.createElement(overridesMap.Heading, null, heading),
@@ -255,40 +266,36 @@ const Calendar = (props) => {
255
266
  react_1.default.createElement(overridesMap.ControlButton, { isActive: calendarCurrentView === 'years', disabled: !calendarViewVariants.includes('years'), title: changeYearButtonTooltip, onClick: handleChangeView(calendarCurrentView === 'years' ? 'days' : 'years') }, getYearLabel(calendarDate)),
256
267
  react_1.default.createElement(overridesMap.ControlButton, { iconOnly: true, onClick: handleChangeMonthClick('next'), title: nextMonthButtonTooltip, disabled: calendarCurrentView !== 'days' },
257
268
  react_1.default.createElement(overridesMap.IconNext, null)))),
258
- react_1.default.createElement(overridesMap.WeekDaysBar, { locale: locale, week: getWeeks(calendarDate)[0], format: weekDayLabelFormat || 'short' }),
269
+ calendarCurrentView === 'days' && (react_1.default.createElement(overridesMap.WeekDaysBar, { locale: locale, week: weeks[0], format: weekDayLabelFormat || 'short' })),
259
270
  react_1.default.createElement(overridesMap.Body, null,
260
- calendarCurrentView === 'years' && (react_1.default.createElement(overridesMap.YearsSelector, null, getYearsRange(minDate, maxDate).map(year => {
261
- const a = Array.isArray(calendarValue) ? calendarValue : [calendarValue];
262
- const isSelected = a.find(d => d.getFullYear() === year) !== undefined;
271
+ calendarCurrentView === 'years' && (react_1.default.createElement(overridesMap.YearsSelector, null, yearsRange.map(year => {
272
+ const isSelected = calendarDate.getFullYear() === year;
263
273
  return (react_1.default.createElement(overridesMap.YearCell, { key: year, accentColor: accentColor, isSelected: isSelected, onClick: handleYearSelected(year) }, getYearLabel(new Date(year, calendarDate.getMonth(), calendarDate.getDate(), 0, 0, 0, 0))));
264
274
  }))),
265
- calendarCurrentView === 'months' && (react_1.default.createElement(overridesMap.MonthsSelector, null, getMonthsRange(minDate, maxDate).map(monthIndex => {
266
- const a = Array.isArray(calendarValue) ? calendarValue : [calendarValue];
267
- const isSelected = a.find(d => d.getMonth() === monthIndex) !== undefined;
268
- return (react_1.default.createElement(overridesMap.MonthCell, { key: monthIndex, accentColor: accentColor, isSelected: isSelected, onClick: handleMonthSelected(monthIndex) }, getMonthLabel(new Date(calendarDate.getFullYear(), monthIndex, 1, 0, 0, 0, 0))));
275
+ calendarCurrentView === 'months' && (react_1.default.createElement(overridesMap.MonthsSelector, null, monthsRange.map(monthIndex => {
276
+ const isSelected = calendarDate.getMonth() === monthIndex;
277
+ return (react_1.default.createElement(overridesMap.MonthCell, { key: monthIndex + monthsRange[monthIndex], accentColor: accentColor, isSelected: isSelected, onClick: handleMonthSelected(monthIndex) }, getMonthLabel(new Date(calendarDate.getFullYear(), monthIndex, 1, 0, 0, 0, 0))));
269
278
  }))),
270
- calendarCurrentView === 'days' && (react_1.default.createElement(overridesMap.DateContainer, null, getWeeks(calendarDate).map(week => (react_1.default.createElement(overridesMap.WeekRow, { key: week.weekNumber.toString() }, week.days.map(day => {
279
+ calendarCurrentView === 'days' && (react_1.default.createElement(overridesMap.DateContainer, null, getWeeks(calendarDate).map(week => (react_1.default.createElement(overridesMap.WeekRow, { key: week.weekNumber }, week.days.map(day => {
271
280
  if (day.date.getMonth() === calendarDate.getMonth()) {
272
281
  const badge = badges.find(b => isSameDay(b.date, day.date));
273
- const a = Array.isArray(calendarValue)
274
- ? calendarValue
275
- : [calendarValue, calendarValue];
276
- const isSelected = isSameDay(a[0], day.date) || isSameDay(a[1], day.date);
277
- const fill = Array.isArray(calendarValue)
278
- ? day.date.getTime() > calendarValue[0].getTime() &&
279
- day.date.getTime() < calendarValue[1].getTime()
280
- : false;
281
- return (react_1.default.createElement(overridesMap.Cell, { key: day.date.getTime(), isToday: markToday && day.isToday, isDisabled: day.isDisabled, accentColor: accentColor, isSelected: isSelected, onClick: handleCellDateClick(day.date), fill: fill },
282
+ // Normalize range order
283
+ const [from, to] = normalizedRange;
284
+ const fill = Array.isArray(calendarValue) &&
285
+ day.date.getTime() >= from.getTime() &&
286
+ day.date.getTime() <= to.getTime();
287
+ const isSelected = isSameDay(from, day.date) || isSameDay(to, day.date);
288
+ return (react_1.default.createElement(overridesMap.Cell, { key: day.date.getTime(), isToday: markToday && day.isToday, isDisabled: day.isDisabled, accentColor: accentColor, isSelected: isSelected, fill: fill, onClick: handleCellDateClick(day.date) },
282
289
  getDayLabel(day.date),
283
- typeof badge !== 'undefined' && (react_1.default.createElement(overridesMap.DayBadge, { badgeContent: badge.badgeContent, isToday: day.isToday, accentColor: badge.accentColor }))));
290
+ badge && (react_1.default.createElement(overridesMap.DayBadge, { badgeContent: badge.badgeContent, isToday: day.isToday, accentColor: badge.accentColor }))));
284
291
  }
285
292
  return react_1.default.createElement(overridesMap.EmptyCell, { key: day.date.getTime() });
286
293
  }))))))),
287
294
  (typeof resetButtonLabel !== 'undefined' ||
288
- typeof toodayButtonLabel !== 'undefined' ||
295
+ typeof todayButtonLabel !== 'undefined' ||
289
296
  typeof footer !== 'undefined') && (react_1.default.createElement(overridesMap.Footer, null,
290
297
  typeof footer !== 'undefined' && react_1.default.createElement(react_1.default.Fragment, null, footer),
291
- typeof toodayButtonLabel !== 'undefined' && (react_1.default.createElement(overridesMap.ControlButton, { onClick: handleToday }, toodayButtonLabel)),
298
+ typeof todayButtonLabel !== 'undefined' && (react_1.default.createElement(overridesMap.ControlButton, { onClick: handleToday }, todayButtonLabel)),
292
299
  typeof resetButtonLabel !== 'undefined' && (react_1.default.createElement(overridesMap.ControlButton, { onClick: handleReset }, resetButtonLabel))))));
293
300
  };
294
301
  exports.default = Calendar;
@@ -6,7 +6,10 @@ export type State<Range extends boolean | undefined = undefined> = {
6
6
  readonly calendarViewVariants: readonly CalendarView[];
7
7
  };
8
8
  export type CalendarView = 'days' | 'months' | 'years';
9
- export declare const createDefaultState: <Range_1 extends boolean | undefined = undefined>(range?: Range_1 | undefined) => State<Range_1>;
9
+ export declare const createDefaultState: <Range_1 extends boolean | undefined = undefined>(range?: Range_1 | undefined, params?: {
10
+ views?: readonly CalendarView[];
11
+ initialView?: CalendarView;
12
+ }) => State<Range_1>;
10
13
  export type Action<Range extends boolean | undefined = undefined> = {
11
14
  readonly type: 'setPartial';
12
15
  readonly payload: Partial<State<Range>>;
@@ -1,17 +1,41 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reducer = exports.createDefaultState = void 0;
4
- const createDefaultState = (range) => {
4
+ const createDefaultState = (range, params) => {
5
+ const { views, initialView } = params || {};
5
6
  const currentDate = new Date();
6
7
  const nextDate = new Date();
7
8
  nextDate.setDate(nextDate.getDate() + 3);
9
+ let calendarViewVariants = ['days', 'months', 'years'];
10
+ let calendarCurrentView = 'days';
11
+ if (views && typeof initialView === 'string') {
12
+ if (!views.includes(initialView)) {
13
+ throw new Error(`Property views must be contained prperty initialView`);
14
+ }
15
+ calendarCurrentView = initialView;
16
+ calendarViewVariants = views;
17
+ }
18
+ if (views && typeof initialView !== 'string') {
19
+ if (views.includes('days')) {
20
+ calendarCurrentView = 'days';
21
+ calendarViewVariants = views;
22
+ }
23
+ else {
24
+ calendarCurrentView = views[0];
25
+ calendarViewVariants = views;
26
+ }
27
+ }
28
+ if (!views && typeof initialView === 'string') {
29
+ calendarViewVariants = ['days', 'months', 'years'];
30
+ calendarCurrentView = initialView;
31
+ }
8
32
  return {
9
33
  calendarValue: range
10
34
  ? [currentDate, nextDate]
11
35
  : new Date(),
12
36
  calendarDate: range ? currentDate : new Date(),
13
- calendarCurrentView: 'days',
14
- calendarViewVariants: ['years', 'months', 'days'],
37
+ calendarCurrentView,
38
+ calendarViewVariants,
15
39
  };
16
40
  };
17
41
  exports.createDefaultState = createDefaultState;