kamotive_ui 1.2.7 → 1.2.9

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.
Files changed (38) hide show
  1. package/dist/Icons/ChevronLeft/ChevronLeft.d.ts +6 -0
  2. package/dist/Icons/ChevronLeft/ChevronLeft.js +5 -0
  3. package/dist/Icons/ChevronRight/ChevronRight.d.ts +6 -0
  4. package/dist/Icons/ChevronRight/ChevronRight.js +5 -0
  5. package/dist/Icons/index.d.ts +2 -0
  6. package/dist/Icons/index.js +2 -0
  7. package/dist/Intro/Welcome.module.css +4 -5
  8. package/dist/colors.css +1 -0
  9. package/dist/components/Breadcrumb/Breadcrumb.d.ts +3 -0
  10. package/dist/components/Breadcrumb/Breadcrumb.js +17 -0
  11. package/dist/components/Breadcrumb/Breadcrumb.module.css +30 -0
  12. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +3 -0
  13. package/dist/components/Breadcrumbs/Breadcrumbs.js +10 -0
  14. package/dist/components/Breadcrumbs/Breadcrumbs.module.css +13 -0
  15. package/dist/components/Button/Button.js +3 -3
  16. package/dist/components/ColorPicker/ColorPicker.module.css +33 -39
  17. package/dist/components/DateInput/DateInput.d.ts +12 -0
  18. package/dist/components/DateInput/DateInput.js +336 -0
  19. package/dist/components/DateInput/DateInput.module.css +425 -0
  20. package/dist/components/Dropdown/Dropdown.module.css +17 -10
  21. package/dist/components/FileAttach/FileAttach.js +3 -3
  22. package/dist/components/Input/Input.module.css +8 -8
  23. package/dist/components/Loader/Loader.js +3 -3
  24. package/dist/components/ProgressBar/ProgressBar.js +1 -2
  25. package/dist/components/ProgressBar/ProgressBar.module.css +1 -2
  26. package/dist/components/Snackbar/Snackbar.js +2 -3
  27. package/dist/components/Tab/Tab.js +1 -2
  28. package/dist/components/Tab/Tab.module.css +2 -1
  29. package/dist/components/Tabs/Tabs.module.css +3 -3
  30. package/dist/components/Tag/Tag.js +1 -1
  31. package/dist/components/Tag/Tag.module.css +2 -2
  32. package/dist/components/ToggleButton/ToggleButton.module.css +46 -47
  33. package/dist/components/Typography/Typography.module.css +74 -67
  34. package/dist/fonts.css +9 -8
  35. package/dist/index.d.ts +2 -1
  36. package/dist/index.js +1 -0
  37. package/dist/types/index.d.ts +53 -0
  38. package/package.json +2 -1
@@ -0,0 +1,336 @@
1
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState, } from 'react';
2
+ import styles from './DateInput.module.css';
3
+ import classNames from 'classnames';
4
+ import { Typography } from '../Typography/Typography';
5
+ import DatePicker from 'react-datepicker';
6
+ import { IconCalendar10 } from '../../Icons/IconCalendar/IconCalendar10';
7
+ import 'react-datepicker/dist/react-datepicker.css';
8
+ import { registerLocale } from 'react-datepicker';
9
+ import { ru } from 'date-fns/locale/ru';
10
+ import { ChevronRight } from '../../Icons/ChevronRight/ChevronRight';
11
+ import { ChevronLeft } from '../../Icons/ChevronLeft/ChevronLeft';
12
+ import { Button } from '../Button/Button';
13
+ registerLocale('ru', ru);
14
+ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, className }, ref) => {
15
+ const inputRef = useRef(null);
16
+ const [selectedPart, setSelectedPart] = useState(null);
17
+ const [tempInput, setTempInput] = useState('');
18
+ const [hasFocus, setHasFocus] = useState(false);
19
+ const [shouldReselect, setShouldReselect] = useState(false);
20
+ const [input, setInput] = useState(value);
21
+ const positions = {
22
+ day: { start: 0, end: 2 },
23
+ month: { start: 3, end: 5 },
24
+ year: { start: 6, end: 10 },
25
+ };
26
+ const selectDatePart = (part) => {
27
+ setSelectedPart(part);
28
+ setTempInput('');
29
+ setShouldReselect(true);
30
+ };
31
+ const highlightDatePart = () => {
32
+ if (!shouldReselect || !inputRef.current || !hasFocus || selectedPart === null)
33
+ return;
34
+ const pos = positions[selectedPart];
35
+ if (inputRef.current && document.activeElement === inputRef.current) {
36
+ inputRef.current.setSelectionRange(pos.start, pos.end);
37
+ }
38
+ };
39
+ const updateInputValue = (char, position) => {
40
+ setShouldReselect(true);
41
+ setInput(input.substring(0, position) + char + input.substring(position + char.length));
42
+ };
43
+ const handleClick = (e) => {
44
+ e.preventDefault();
45
+ if (onClick)
46
+ onClick(e);
47
+ if (!inputRef.current)
48
+ return;
49
+ setHasFocus(true);
50
+ const cursorPosition = inputRef.current.selectionStart || 0;
51
+ let newSelectedPart;
52
+ if (cursorPosition <= positions.day.end) {
53
+ newSelectedPart = 'day';
54
+ }
55
+ else if (cursorPosition <= positions.month.end) {
56
+ newSelectedPart = 'month';
57
+ }
58
+ else {
59
+ newSelectedPart = 'year';
60
+ }
61
+ selectDatePart(newSelectedPart);
62
+ };
63
+ const handleKeyDown = (e) => {
64
+ if (!inputRef.current || !onDateChange || selectedPart === null)
65
+ return;
66
+ if (e.key === 'ArrowLeft') {
67
+ e.preventDefault();
68
+ if (selectedPart === 'month') {
69
+ selectDatePart('day');
70
+ }
71
+ else if (selectedPart === 'year') {
72
+ selectDatePart('month');
73
+ }
74
+ }
75
+ else if (e.key === 'ArrowRight' || e.key === '.') {
76
+ e.preventDefault();
77
+ if (selectedPart === 'day') {
78
+ selectDatePart('month');
79
+ }
80
+ else if (selectedPart === 'month') {
81
+ selectDatePart('year');
82
+ }
83
+ }
84
+ else if (/^\d$/.test(e.key)) {
85
+ e.preventDefault();
86
+ if (!/^\d{2}\.\d{2}\.\d{4}$/.test(input)) {
87
+ const today = new Date();
88
+ handleDateUpdate(today, e.key);
89
+ return;
90
+ }
91
+ const [day, month, year] = input.split('.').map((part) => parseInt(part, 10));
92
+ const currentDate = new Date(year, month - 1, day);
93
+ handleDateUpdate(currentDate, e.key);
94
+ }
95
+ else if (e.key === 'Tab') {
96
+ if (e.shiftKey) {
97
+ e.preventDefault();
98
+ if (selectedPart === 'year') {
99
+ selectDatePart('month');
100
+ }
101
+ else if (selectedPart === 'month') {
102
+ selectDatePart('day');
103
+ }
104
+ }
105
+ else {
106
+ e.preventDefault();
107
+ if (selectedPart === 'day') {
108
+ selectDatePart('month');
109
+ }
110
+ else if (selectedPart === 'month') {
111
+ selectDatePart('year');
112
+ }
113
+ }
114
+ }
115
+ else if (e.key === 'Backspace' || e.key === 'Delete') {
116
+ e.preventDefault();
117
+ selectDatePart(selectedPart);
118
+ }
119
+ };
120
+ const handleDateUpdate = (currentDate, key) => {
121
+ if (!onDateChange || selectedPart === null)
122
+ return;
123
+ const newTempInput = tempInput + key;
124
+ setTempInput(newTempInput);
125
+ let newDate = new Date(currentDate);
126
+ if (selectedPart === 'day') {
127
+ if (newTempInput.length === 1) {
128
+ updateInputValue(key, positions.day.start);
129
+ return;
130
+ }
131
+ updateInputValue(key, positions.day.start + 1);
132
+ let newDay = parseInt(newTempInput, 10);
133
+ newDate.setDate(newDay);
134
+ onDateChange(newDate);
135
+ selectDatePart('month');
136
+ }
137
+ else if (selectedPart === 'month') {
138
+ if (newTempInput.length === 1) {
139
+ updateInputValue(key, positions.month.start);
140
+ return;
141
+ }
142
+ updateInputValue(key, positions.day.start + 1);
143
+ let newMonth = parseInt(newTempInput, 10);
144
+ newDate.setMonth(newMonth - 1);
145
+ onDateChange(newDate);
146
+ selectDatePart('year');
147
+ }
148
+ else if (selectedPart === 'year') {
149
+ if (newTempInput.length < 4) {
150
+ updateInputValue(key, positions.year.start + newTempInput.length - 1);
151
+ return;
152
+ }
153
+ let newYear = parseInt(newTempInput, 10);
154
+ newDate.setFullYear(newYear);
155
+ onDateChange(newDate);
156
+ if (onClose) {
157
+ onClose();
158
+ }
159
+ }
160
+ };
161
+ const handleFocus = () => {
162
+ setHasFocus(true);
163
+ selectDatePart('day');
164
+ };
165
+ const handleBlur = () => {
166
+ setHasFocus(false);
167
+ setTempInput('');
168
+ setSelectedPart(null);
169
+ };
170
+ const removeSelection = useCallback(() => {
171
+ if (inputRef.current) {
172
+ const length = inputRef.current.value.length;
173
+ inputRef.current.setSelectionRange(length, length);
174
+ }
175
+ }, []);
176
+ useEffect(() => {
177
+ setInput(value);
178
+ }, [value]);
179
+ useEffect(() => {
180
+ setTempInput('');
181
+ }, [value]);
182
+ useEffect(() => {
183
+ highlightDatePart();
184
+ }, [selectedPart, highlightDatePart, shouldReselect]);
185
+ useImperativeHandle(ref, () => ({
186
+ removeSelection,
187
+ }), [removeSelection]);
188
+ return (React.createElement("input", { ref: inputRef, value: input, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, readOnly: true, className: className }));
189
+ });
190
+ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg', value, style, className, disabled = false, readOnly = disabled, isLeftLabel = false, icon, error = false, helperText, onChange, onBlur, required = false, minDate = new Date('1975-12-31'), maxDate = new Date('2074-12-31'), inputClassName, calendarClassName, dateFormat = 'dd.MM.yyyy', }) => {
191
+ const wrapperClassess = classNames(styles['wrapper--input'], className, {
192
+ [styles['wrapper--left']]: isLeftLabel,
193
+ [styles['wrapper--input-label']]: label && !isLeftLabel && !required,
194
+ [styles['wrapper--input-helperText']]: error,
195
+ });
196
+ const inputClassess = classNames(styles.input, styles[size], {
197
+ [styles['input--error']]: error,
198
+ [styles['readOnly']]: readOnly,
199
+ [styles['input--withIcon']]: true,
200
+ [styles['input--left']]: isLeftLabel,
201
+ });
202
+ const labelClasses = classNames(styles.label, styles[size], {
203
+ [styles['label--default']]: !isLeftLabel,
204
+ [styles['label--left']]: isLeftLabel,
205
+ [styles['label--required']]: required,
206
+ });
207
+ const [selectedDate, setSelectedDate] = useState(value ? new Date(value) : new Date());
208
+ const [isMonthPickerOpen, setIsMonthPickerOpen] = useState(false);
209
+ const datePickerRef = useRef(null);
210
+ const inputRef = useRef(null);
211
+ const months = [
212
+ 'Январь',
213
+ 'Февраль',
214
+ 'Март',
215
+ 'Апрель',
216
+ 'Май',
217
+ 'Июнь',
218
+ 'Июль',
219
+ 'Август',
220
+ 'Сентябрь',
221
+ 'Октябрь',
222
+ 'Ноябрь',
223
+ 'Декабрь',
224
+ ];
225
+ const years = Array.from({ length: maxDate.getFullYear() - minDate.getFullYear() }, (_, i) => minDate.getFullYear() + i);
226
+ const handleDateChange = (date) => {
227
+ if (date) {
228
+ setSelectedDate(date);
229
+ if (onChange) {
230
+ onChange(date);
231
+ }
232
+ }
233
+ setTimeout(() => {
234
+ if (inputRef.current) {
235
+ inputRef.current.removeSelection();
236
+ }
237
+ }, 0);
238
+ };
239
+ const handleCustomInputChange = (date) => {
240
+ setSelectedDate(date);
241
+ };
242
+ const handleCloseDatePicker = () => {
243
+ if (datePickerRef.current) {
244
+ datePickerRef.current.setOpen(false);
245
+ }
246
+ };
247
+ const MonthPicker = ({ date }) => {
248
+ const itemClasses = (type, isActive) => classNames(styles.listItem, styles[`listItem--${type}`], {
249
+ [styles['item--active']]: isActive,
250
+ });
251
+ const [currentMonth, setCurrentMonth] = useState(date.getMonth());
252
+ const [currentYear, setCurrentYear] = useState(date.getFullYear());
253
+ const yearRefs = useRef([]);
254
+ const monthRefs = useRef([]);
255
+ const getRef = (refs, index) => {
256
+ return (element) => {
257
+ if (element && refs.current)
258
+ refs.current[index] = element;
259
+ };
260
+ };
261
+ useEffect(() => {
262
+ var _a;
263
+ if (yearRefs.current[years.indexOf(currentYear)]) {
264
+ (_a = yearRefs.current[years.indexOf(currentYear)]) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
265
+ behavior: 'smooth',
266
+ block: 'nearest',
267
+ });
268
+ }
269
+ }, [currentYear]);
270
+ useEffect(() => {
271
+ var _a;
272
+ if (monthRefs.current[currentMonth]) {
273
+ (_a = monthRefs.current[currentMonth]) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
274
+ behavior: 'smooth',
275
+ block: 'nearest',
276
+ });
277
+ }
278
+ }, [currentMonth]);
279
+ return (React.createElement("div", { className: `${styles.monthPicker} ${styles.calendar}` },
280
+ React.createElement("div", { className: styles.monthPickerWrapper },
281
+ React.createElement("div", { className: styles.monthContainer }, months.map((month, index) => {
282
+ const monthClasses = itemClasses('month', months.indexOf(month) === currentMonth);
283
+ return (React.createElement("div", { key: month, ref: getRef(monthRefs, index), className: monthClasses, onClick: () => {
284
+ setCurrentMonth(months.indexOf(month));
285
+ } }, month));
286
+ })),
287
+ React.createElement("div", { className: styles.monthContainer }, years.map((year, index) => {
288
+ const yearClasses = itemClasses('year', year === currentYear);
289
+ return (React.createElement("div", { key: year, ref: getRef(yearRefs, index), className: yearClasses, onClick: () => {
290
+ setCurrentYear(year);
291
+ } }, year));
292
+ }))),
293
+ React.createElement("div", { className: styles.buttonContainer },
294
+ React.createElement(Button, { condition: "info", onClick: () => {
295
+ setIsMonthPickerOpen(false);
296
+ } }, "\u041E\u0442\u043C\u0435\u043D\u0430"),
297
+ React.createElement(Button, { onClick: () => {
298
+ date.setMonth(currentMonth);
299
+ date.setFullYear(currentYear);
300
+ setIsMonthPickerOpen(false);
301
+ } }, "\u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C"))));
302
+ };
303
+ const getMonthPickerWithDate = (date) => {
304
+ return () => React.createElement(MonthPicker, { date: date });
305
+ };
306
+ const renderCustomHeader = ({ date, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled, }) => {
307
+ return (React.createElement("div", { className: styles.calendarHeader },
308
+ React.createElement("button", { type: "button", onClick: decreaseMonth, disabled: prevMonthButtonDisabled, className: styles.calendarNavButton },
309
+ React.createElement(ChevronLeft, null)),
310
+ React.createElement("div", { className: styles.monthDisplay, onClick: () => {
311
+ setIsMonthPickerOpen(true);
312
+ } },
313
+ months[date.getMonth()],
314
+ ", ",
315
+ date.getFullYear()),
316
+ React.createElement("button", { type: "button", onClick: increaseMonth, disabled: nextMonthButtonDisabled, className: styles.calendarNavButton },
317
+ React.createElement(ChevronRight, null))));
318
+ };
319
+ const renderDayContents = (day, date) => {
320
+ return React.createElement("div", { className: styles.calendarDay }, day);
321
+ };
322
+ return (React.createElement("div", { className: wrapperClassess, style: style },
323
+ label && (React.createElement(Typography, { variant: "Caption", className: labelClasses }, label)),
324
+ React.createElement("div", { className: styles.icon, onClick: () => { var _a; return (_a = datePickerRef.current) === null || _a === void 0 ? void 0 : _a.setOpen(true); } }, icon || React.createElement(IconCalendar10, null)),
325
+ React.createElement(DatePicker, Object.assign({ id: id, ref: datePickerRef, selected: selectedDate, onChange: handleDateChange, onBlur: onBlur, dateFormat: dateFormat, locale: "ru", readOnly: readOnly, showPopperArrow: false, calendarClassName: classNames(styles.calendar, calendarClassName), popperClassName: styles.calendarPopper, onCalendarClose: () => setIsMonthPickerOpen(false), minDate: minDate, maxDate: maxDate, inline: false, calendarStartDay: 1, dayClassName: (date) => {
326
+ return date.getMonth() === (selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.getMonth()) && date.getFullYear() === (selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.getFullYear())
327
+ ? 'current-month-day'
328
+ : '';
329
+ } }, (isMonthPickerOpen
330
+ ? { calendarContainer: getMonthPickerWithDate(selectedDate || new Date()) }
331
+ : {
332
+ renderCustomHeader: renderCustomHeader,
333
+ renderDayContents: renderDayContents,
334
+ }), { customInput: React.createElement(CustomInput, { ref: inputRef, className: classNames(inputClassess, inputClassName), onDateChange: handleCustomInputChange, onClose: handleCloseDatePicker }) })),
335
+ error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText, styles[size]) }, helperText))));
336
+ };