kamotive_ui 1.2.22 → 1.2.24
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/components/DateInput/DateInput.js +68 -38
- package/dist/components/DateInput/DateInput.module.css +5 -6
- package/dist/components/Dropdown/Dropdown.d.ts +2 -1
- package/dist/components/Dropdown/Dropdown.js +151 -47
- package/dist/components/Dropdown/Dropdown.module.css +52 -11
- package/dist/components/Input/Input.module.css +0 -1
- package/dist/components/Link/Link.d.ts +3 -0
- package/dist/components/Link/Link.js +7 -0
- package/dist/components/Link/Link.module.css +11 -0
- package/dist/components/Tooltip/Tooltip.module.css +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/types/index.d.ts +18 -10
- package/package.json +1 -1
|
@@ -7,22 +7,27 @@ import { IconCalendar } from '../../Icons/IconCalendar/IconCalendar';
|
|
|
7
7
|
import 'react-datepicker/dist/react-datepicker.css';
|
|
8
8
|
import { registerLocale } from 'react-datepicker';
|
|
9
9
|
import { ru } from 'date-fns/locale/ru';
|
|
10
|
+
import { enUS } from 'date-fns/locale/en-US';
|
|
10
11
|
import { ChevronRight } from '../../Icons/ChevronRight/ChevronRight';
|
|
11
12
|
import { ChevronLeft } from '../../Icons/ChevronLeft/ChevronLeft';
|
|
12
13
|
import { Button } from '../Button/Button';
|
|
13
14
|
registerLocale('ru', ru);
|
|
14
|
-
|
|
15
|
+
registerLocale('en', enUS);
|
|
16
|
+
const CustomInput = forwardRef(({ value = '', lng, onClick, onDateChange, onClose, className, disabled = false, readOnly = false, dateFormat = 'dd.MM.yyyy' }, ref) => {
|
|
15
17
|
const inputRef = useRef(null);
|
|
16
18
|
const [selectedPart, setSelectedPart] = useState(null);
|
|
17
19
|
const [tempInput, setTempInput] = useState('');
|
|
18
20
|
const [hasFocus, setHasFocus] = useState(false);
|
|
19
21
|
const [shouldReselect, setShouldReselect] = useState(false);
|
|
20
22
|
const [input, setInput] = useState(value);
|
|
23
|
+
const separator = dateFormat.includes('.') ? '.' : dateFormat.includes('-') ? '-' : '/';
|
|
21
24
|
const positions = {
|
|
22
25
|
day: { start: 0, end: 2 },
|
|
23
26
|
month: { start: 3, end: 5 },
|
|
24
27
|
year: { start: 6, end: 10 },
|
|
25
28
|
};
|
|
29
|
+
const placeholderText = lng === 'ru' ? 'Не выбрано' : 'Not selected';
|
|
30
|
+
const displayValue = value || placeholderText;
|
|
26
31
|
const selectDatePart = (part) => {
|
|
27
32
|
setSelectedPart(part);
|
|
28
33
|
setTempInput('');
|
|
@@ -49,18 +54,20 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
49
54
|
if (!inputRef.current)
|
|
50
55
|
return;
|
|
51
56
|
setHasFocus(true);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
if (value) {
|
|
58
|
+
const cursorPosition = inputRef.current.selectionStart || 0;
|
|
59
|
+
let newSelectedPart;
|
|
60
|
+
if (cursorPosition <= positions.day.end) {
|
|
61
|
+
newSelectedPart = 'day';
|
|
62
|
+
}
|
|
63
|
+
else if (cursorPosition <= positions.month.end) {
|
|
64
|
+
newSelectedPart = 'month';
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
newSelectedPart = 'year';
|
|
68
|
+
}
|
|
69
|
+
selectDatePart(newSelectedPart);
|
|
62
70
|
}
|
|
63
|
-
selectDatePart(newSelectedPart);
|
|
64
71
|
};
|
|
65
72
|
const handleKeyDown = (e) => {
|
|
66
73
|
if (!inputRef.current || !onDateChange || selectedPart === null)
|
|
@@ -74,7 +81,7 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
74
81
|
selectDatePart('month');
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
|
-
else if (e.key === 'ArrowRight' || e.key ===
|
|
84
|
+
else if (e.key === 'ArrowRight' || e.key === separator) {
|
|
78
85
|
e.preventDefault();
|
|
79
86
|
if (selectedPart === 'day') {
|
|
80
87
|
selectDatePart('month');
|
|
@@ -85,12 +92,13 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
85
92
|
}
|
|
86
93
|
else if (/^\d$/.test(e.key)) {
|
|
87
94
|
e.preventDefault();
|
|
88
|
-
|
|
95
|
+
const dateRegex = new RegExp(`^\\d{2}\\${separator}\\d{2}\\${separator}\\d{4}$`);
|
|
96
|
+
if (!dateRegex.test(input)) {
|
|
89
97
|
const today = new Date();
|
|
90
98
|
handleDateUpdate(today, e.key);
|
|
91
99
|
return;
|
|
92
100
|
}
|
|
93
|
-
const [day, month, year] = input.split(
|
|
101
|
+
const [day, month, year] = input.split(separator).map((part) => parseInt(part, 10));
|
|
94
102
|
const currentDate = new Date(year, month - 1, day);
|
|
95
103
|
handleDateUpdate(currentDate, e.key);
|
|
96
104
|
}
|
|
@@ -141,7 +149,7 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
141
149
|
updateInputValue(key, positions.month.start);
|
|
142
150
|
return;
|
|
143
151
|
}
|
|
144
|
-
updateInputValue(key, positions.
|
|
152
|
+
updateInputValue(key, positions.month.start + 1);
|
|
145
153
|
let newMonth = parseInt(newTempInput, 10);
|
|
146
154
|
newDate.setMonth(newMonth - 1);
|
|
147
155
|
onDateChange(newDate);
|
|
@@ -162,7 +170,9 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
162
170
|
};
|
|
163
171
|
const handleFocus = () => {
|
|
164
172
|
setHasFocus(true);
|
|
165
|
-
|
|
173
|
+
if (value) {
|
|
174
|
+
selectDatePart('day');
|
|
175
|
+
}
|
|
166
176
|
};
|
|
167
177
|
const handleBlur = () => {
|
|
168
178
|
setHasFocus(false);
|
|
@@ -189,9 +199,9 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
189
199
|
useImperativeHandle(ref, () => ({
|
|
190
200
|
removeSelection,
|
|
191
201
|
}), [removeSelection]);
|
|
192
|
-
return (React.createElement("input", { ref: inputRef, value: input, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, readOnly: readOnly, disabled: disabled, className: className }));
|
|
202
|
+
return (React.createElement("input", { ref: inputRef, value: input || displayValue, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onChange: () => { }, readOnly: !value || readOnly, disabled: disabled, className: className }));
|
|
193
203
|
});
|
|
194
|
-
export const DateInput = ({ id, label = 'Выберите дату', size = 'lg', value, style, className, disabled = false, readOnly = false, 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', }) => {
|
|
204
|
+
export const DateInput = ({ id, label = 'Выберите дату', size = 'lg', value, style, className, disabled = false, readOnly = false, isLeftLabel = false, icon, error = false, helperText, onChange, onBlur, required = false, lng = 'ru', minDate = new Date('1975-12-31'), maxDate = new Date('2074-12-31'), inputClassName, calendarClassName, dateFormat = 'dd.MM.yyyy', }) => {
|
|
195
205
|
const wrapperClassess = classNames(styles['wrapper--input'], className, {
|
|
196
206
|
[styles['wrapper--left']]: isLeftLabel,
|
|
197
207
|
[styles['wrapper--input-label']]: label && !isLeftLabel && !required,
|
|
@@ -208,24 +218,40 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
208
218
|
[styles['label--left']]: isLeftLabel,
|
|
209
219
|
[styles['label--required']]: required,
|
|
210
220
|
});
|
|
211
|
-
const [selectedDate, setSelectedDate] = useState(value ? new Date(value) :
|
|
221
|
+
const [selectedDate, setSelectedDate] = useState(value ? new Date(value) : null);
|
|
212
222
|
const [isMonthPickerOpen, setIsMonthPickerOpen] = useState(false);
|
|
213
223
|
const datePickerRef = useRef(null);
|
|
214
224
|
const inputRef = useRef(null);
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
225
|
+
const weekDays = lng === 'ru' ? ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'] : ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
|
|
226
|
+
const months = lng === 'ru'
|
|
227
|
+
? [
|
|
228
|
+
'Январь',
|
|
229
|
+
'Февраль',
|
|
230
|
+
'Март',
|
|
231
|
+
'Апрель',
|
|
232
|
+
'Май',
|
|
233
|
+
'Июнь',
|
|
234
|
+
'Июль',
|
|
235
|
+
'Август',
|
|
236
|
+
'Сентябрь',
|
|
237
|
+
'Октябрь',
|
|
238
|
+
'Ноябрь',
|
|
239
|
+
'Декабрь',
|
|
240
|
+
]
|
|
241
|
+
: [
|
|
242
|
+
'January',
|
|
243
|
+
'February',
|
|
244
|
+
'March',
|
|
245
|
+
'April',
|
|
246
|
+
'May',
|
|
247
|
+
'June',
|
|
248
|
+
'July',
|
|
249
|
+
'August',
|
|
250
|
+
'September',
|
|
251
|
+
'October',
|
|
252
|
+
'November',
|
|
253
|
+
'December',
|
|
254
|
+
];
|
|
229
255
|
const years = Array.from({ length: maxDate.getFullYear() - minDate.getFullYear() }, (_, i) => minDate.getFullYear() + i);
|
|
230
256
|
const handleDateChange = (date) => {
|
|
231
257
|
if (date) {
|
|
@@ -297,12 +323,12 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
297
323
|
React.createElement("div", { className: styles.buttonContainer },
|
|
298
324
|
React.createElement(Button, { condition: "info", onClick: () => {
|
|
299
325
|
setIsMonthPickerOpen(false);
|
|
300
|
-
} }, "
|
|
326
|
+
} }, lng === 'ru' ? "Отмена" : "Cancel"),
|
|
301
327
|
React.createElement(Button, { onClick: () => {
|
|
302
328
|
date.setMonth(currentMonth);
|
|
303
329
|
date.setFullYear(currentYear);
|
|
304
330
|
setIsMonthPickerOpen(false);
|
|
305
|
-
} }, "
|
|
331
|
+
} }, lng === 'ru' ? "Применить" : "Apply"))));
|
|
306
332
|
};
|
|
307
333
|
const getMonthPickerWithDate = (date) => {
|
|
308
334
|
return () => React.createElement(MonthPicker, { date: date });
|
|
@@ -326,7 +352,11 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
326
352
|
return (React.createElement("div", { className: wrapperClassess, style: style },
|
|
327
353
|
label && (React.createElement(Typography, { variant: "Caption", className: labelClasses }, label)),
|
|
328
354
|
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(IconCalendar, null)),
|
|
329
|
-
React.createElement(DatePicker, Object.assign({ id: id, ref: datePickerRef, selected: selectedDate, onChange: handleDateChange, onBlur: onBlur, dateFormat: dateFormat, locale:
|
|
355
|
+
React.createElement(DatePicker, Object.assign({ id: id, ref: datePickerRef, selected: selectedDate, onChange: handleDateChange, onBlur: onBlur, dateFormat: dateFormat, locale: lng === 'ru' ? 'ru' : 'en', readOnly: readOnly, disabled: disabled, showPopperArrow: false, calendarClassName: classNames(styles.calendar, calendarClassName), popperClassName: styles.calendarPopper, onCalendarClose: () => setIsMonthPickerOpen(false), minDate: minDate, maxDate: maxDate, inline: false, calendarStartDay: 1, formatWeekDay: (dayName) => {
|
|
356
|
+
const dayIndex = ['понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота', 'воскресенье']
|
|
357
|
+
.findIndex(day => day === dayName);
|
|
358
|
+
return weekDays[dayIndex];
|
|
359
|
+
}, dayClassName: (date) => {
|
|
330
360
|
return date.getMonth() === (selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.getMonth()) && date.getFullYear() === (selectedDate === null || selectedDate === void 0 ? void 0 : selectedDate.getFullYear())
|
|
331
361
|
? 'current-month-day'
|
|
332
362
|
: '';
|
|
@@ -335,6 +365,6 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
335
365
|
: {
|
|
336
366
|
renderCustomHeader: renderCustomHeader,
|
|
337
367
|
renderDayContents: renderDayContents,
|
|
338
|
-
}), { customInput: React.createElement(CustomInput, { ref: inputRef, className: classNames(inputClassess, inputClassName), onDateChange: handleCustomInputChange, onClose: handleCloseDatePicker, disabled: disabled, readOnly: readOnly }) })),
|
|
368
|
+
}), { customInput: React.createElement(CustomInput, { ref: inputRef, lng: lng, className: classNames(inputClassess, inputClassName), onDateChange: handleCustomInputChange, onClose: handleCloseDatePicker, disabled: disabled, readOnly: readOnly, dateFormat: dateFormat }) })),
|
|
339
369
|
error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText, styles[size]) }, helperText))));
|
|
340
370
|
};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
.wrapper--input {
|
|
2
2
|
position: relative;
|
|
3
|
-
max-width: 267px;
|
|
4
|
-
width: 100%;
|
|
5
3
|
}
|
|
6
4
|
|
|
7
5
|
.wrapper--input-label {
|
|
@@ -35,6 +33,7 @@
|
|
|
35
33
|
border-radius: 10px;
|
|
36
34
|
display: inline-flex;
|
|
37
35
|
width: 100%;
|
|
36
|
+
box-sizing: border-box;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
.input--left {
|
|
@@ -93,7 +92,7 @@
|
|
|
93
92
|
color: var(--text-dark);
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
.label--default
|
|
95
|
+
.label--default.lg {
|
|
97
96
|
font-size: 12px;
|
|
98
97
|
}
|
|
99
98
|
|
|
@@ -101,7 +100,7 @@
|
|
|
101
100
|
font-size: 10px;
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
.label--default
|
|
103
|
+
.label--default.sm {
|
|
105
104
|
font-size: 16px;
|
|
106
105
|
}
|
|
107
106
|
|
|
@@ -115,11 +114,11 @@
|
|
|
115
114
|
font-size: 14px;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
.label--left
|
|
117
|
+
.label--left.md {
|
|
119
118
|
font-size: 12px;
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
.label--left
|
|
121
|
+
.label--left.sm {
|
|
123
122
|
font-size: 10px;
|
|
124
123
|
}
|
|
125
124
|
|
|
@@ -5,7 +5,7 @@ import { DropdownProps, TOptions } from '../../types';
|
|
|
5
5
|
*/
|
|
6
6
|
export interface DropdownListItemProps {
|
|
7
7
|
item: TOptions | null;
|
|
8
|
-
getOptionLabel?: (
|
|
8
|
+
getOptionLabel?: (option: TOptions) => string;
|
|
9
9
|
size: 'md' | 'lg';
|
|
10
10
|
selectedItem: TOptions | null;
|
|
11
11
|
variant?: 'icons' | 'text';
|
|
@@ -13,6 +13,7 @@ export interface DropdownListItemProps {
|
|
|
13
13
|
isActive?: boolean;
|
|
14
14
|
activeIndex?: number;
|
|
15
15
|
index?: number;
|
|
16
|
+
isChild?: boolean;
|
|
16
17
|
}
|
|
17
18
|
export declare const DropdownListItem: FC<DropdownListItemProps>;
|
|
18
19
|
export declare const Dropdown: FC<DropdownProps>;
|
|
@@ -5,28 +5,86 @@ import { ChevronDown } from '../../Icons/ChevronDown/ChevronDown';
|
|
|
5
5
|
import { ChevronUp } from '../../Icons/ChevronUp/ChevronUp';
|
|
6
6
|
import { IconClose } from '../../Icons/IconClose/IconClose';
|
|
7
7
|
import { IconCheck } from '../../Icons/IconCheck/IconCheck';
|
|
8
|
-
;
|
|
9
8
|
import { Typography } from '../Typography/Typography';
|
|
9
|
+
import { Tooltip } from '../Tooltip/Tooltip';
|
|
10
|
+
const isTextOverflowing = (element) => {
|
|
11
|
+
if (!element)
|
|
12
|
+
return false;
|
|
13
|
+
return element.scrollWidth > element.clientWidth;
|
|
14
|
+
};
|
|
15
|
+
const getComparisonValue = (item, getOptionLabel) => {
|
|
16
|
+
if (!item)
|
|
17
|
+
return null;
|
|
18
|
+
if (getOptionLabel && typeof getOptionLabel === 'function') {
|
|
19
|
+
return getOptionLabel(item);
|
|
20
|
+
}
|
|
21
|
+
// Если есть value, используем его
|
|
22
|
+
if (item.value !== undefined) {
|
|
23
|
+
return item.value;
|
|
24
|
+
}
|
|
25
|
+
// Если есть id, используем его для сравнения
|
|
26
|
+
if (item.id !== undefined) {
|
|
27
|
+
return item.id;
|
|
28
|
+
}
|
|
29
|
+
// Иначе используем сам объект
|
|
30
|
+
return item;
|
|
31
|
+
};
|
|
10
32
|
function checkItem(item, getOptionLabel, disabled, isDivider) {
|
|
11
33
|
if (typeof item === 'object' && item !== null) {
|
|
12
34
|
const itemCopy = Object.assign({}, item);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
35
|
+
// Проверяем только поле value на вложенные объекты
|
|
36
|
+
if (getOptionLabel) {
|
|
37
|
+
const labelResult = getOptionLabel(itemCopy);
|
|
38
|
+
// Если getOptionLabel возвращает массив
|
|
39
|
+
if (Array.isArray(labelResult)) {
|
|
40
|
+
if (!itemCopy.children) {
|
|
41
|
+
itemCopy.children = [];
|
|
42
|
+
}
|
|
43
|
+
labelResult.forEach((labelItem) => {
|
|
44
|
+
const processedLabelItem = checkItem(labelItem, getOptionLabel, disabled, isDivider);
|
|
45
|
+
if (processedLabelItem) {
|
|
46
|
+
itemCopy.children.push(processedLabelItem);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
// Для родительского элемента используем первый элемент массива или name
|
|
50
|
+
const displayValue = labelResult.length > 0
|
|
51
|
+
? typeof labelResult[0] === 'object'
|
|
52
|
+
? labelResult[0].name || labelResult[0].value || 'Группа'
|
|
53
|
+
: labelResult[0]
|
|
54
|
+
: itemCopy.name || 'Группа опций';
|
|
55
|
+
return Object.assign(Object.assign({}, itemCopy), { value: displayValue, disabled: disabled !== null && disabled !== void 0 ? disabled : false, isDivider: isDivider !== null && isDivider !== void 0 ? isDivider : false });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Обычная обработка, если getOptionLabel возвращает строку
|
|
59
|
+
return Object.assign(Object.assign({}, itemCopy), { value: labelResult, disabled: disabled !== null && disabled !== void 0 ? disabled : false, isDivider: isDivider !== null && isDivider !== void 0 ? isDivider : false });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!getOptionLabel && 'value' in itemCopy && itemCopy.value !== null && !React.isValidElement(itemCopy.value)) {
|
|
63
|
+
if (Array.isArray(itemCopy.value)) {
|
|
64
|
+
if (!itemCopy.children) {
|
|
65
|
+
itemCopy.children = [];
|
|
66
|
+
}
|
|
67
|
+
// Обрабатываем каждый элемент массива
|
|
68
|
+
itemCopy.value.forEach((nestedItem) => {
|
|
69
|
+
const processedNestedItem = checkItem(nestedItem, getOptionLabel, disabled, isDivider);
|
|
70
|
+
if (processedNestedItem) {
|
|
71
|
+
itemCopy.children.push(processedNestedItem);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
// Для родительского элемента используем name или первое значение
|
|
75
|
+
itemCopy.value = itemCopy.name || 'Группа опций';
|
|
76
|
+
}
|
|
77
|
+
else if (typeof itemCopy.value === 'object') {
|
|
78
|
+
const nestedItem = checkItem(itemCopy.value, getOptionLabel, disabled, isDivider);
|
|
18
79
|
if (nestedItem) {
|
|
19
80
|
if (!itemCopy.children) {
|
|
20
81
|
itemCopy.children = [];
|
|
21
82
|
}
|
|
22
83
|
itemCopy.children.push(nestedItem);
|
|
23
|
-
|
|
84
|
+
// Заменяем value на обработанное значение
|
|
85
|
+
itemCopy.value = nestedItem.value;
|
|
24
86
|
}
|
|
25
87
|
}
|
|
26
|
-
});
|
|
27
|
-
// проверка на наличие пользовательского поля для вывода(передаваемой функции getOptionLabel)
|
|
28
|
-
if (getOptionLabel) {
|
|
29
|
-
return Object.assign(Object.assign({}, itemCopy), { value: getOptionLabel(itemCopy), disabled: disabled !== null && disabled !== void 0 ? disabled : false, isDivider: isDivider !== null && isDivider !== void 0 ? isDivider : false });
|
|
30
88
|
}
|
|
31
89
|
if ('value' in itemCopy) {
|
|
32
90
|
return Object.assign(Object.assign({}, itemCopy), { disabled: disabled !== null && disabled !== void 0 ? disabled : false, isDivider: isDivider !== null && isDivider !== void 0 ? isDivider : false });
|
|
@@ -52,22 +110,50 @@ function checkItem(item, getOptionLabel, disabled, isDivider) {
|
|
|
52
110
|
return null;
|
|
53
111
|
}
|
|
54
112
|
}
|
|
55
|
-
export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedItem, variant, onChange, isActive, activeIndex, index, }) => {
|
|
56
|
-
var _a;
|
|
113
|
+
export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedItem, variant, onChange, isActive, activeIndex, index, isChild = false, }) => {
|
|
114
|
+
var _a, _b;
|
|
115
|
+
const itemRef = useRef(null);
|
|
116
|
+
const [showTooltip, setShowTooltip] = useState(false);
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
const checkOverflow = () => {
|
|
119
|
+
setShowTooltip(isTextOverflowing(itemRef.current));
|
|
120
|
+
};
|
|
121
|
+
checkOverflow();
|
|
122
|
+
window.addEventListener('resize', checkOverflow);
|
|
123
|
+
return () => {
|
|
124
|
+
window.removeEventListener('resize', checkOverflow);
|
|
125
|
+
};
|
|
126
|
+
}, [getComparisonValue(item, getOptionLabel)]);
|
|
57
127
|
const handleItemClick = useCallback((event) => {
|
|
58
128
|
event.preventDefault();
|
|
59
129
|
event.stopPropagation();
|
|
60
130
|
if (!(item === null || item === void 0 ? void 0 : item.disabled)) {
|
|
61
|
-
|
|
131
|
+
if (!(item === null || item === void 0 ? void 0 : item.children) || item.children.length === 0) {
|
|
132
|
+
onChange(event, item); // Если у элемента есть дети, не выбираем родительский элемент
|
|
133
|
+
}
|
|
62
134
|
}
|
|
63
135
|
}, [item, onChange]);
|
|
64
|
-
const
|
|
136
|
+
const hasChildren = (item === null || item === void 0 ? void 0 : item.children) && item.children.length > 0;
|
|
137
|
+
const itemContainerClasses = classNames(styles[`item--container`], {
|
|
138
|
+
[styles['item--container--active']]: isActive,
|
|
139
|
+
[styles['item--container--parent']]: hasChildren && !isChild,
|
|
140
|
+
[styles['item--container--child']]: isChild,
|
|
141
|
+
});
|
|
65
142
|
const itemClassess = classNames(styles[`item-block`], styles[`button--${size}`], {
|
|
66
143
|
[styles['item-block--disabled']]: item === null || item === void 0 ? void 0 : item.disabled,
|
|
67
144
|
[styles['item-block--active']]: isActive,
|
|
145
|
+
[styles['item-block--parent']]: hasChildren && !isChild, // Стиль для родительских элементов
|
|
146
|
+
[styles['item-block--child']]: isChild, // Стиль для дочерних элементов
|
|
147
|
+
});
|
|
148
|
+
const itemBlock = classNames(styles[`item-block`], styles[`item-block-${variant}`],
|
|
149
|
+
// { [styles[`item-block-${variant}--selected`]]: selectedItem?.value === item?.value },
|
|
150
|
+
{
|
|
151
|
+
[styles[`item-block-${variant}--selected`]]: getComparisonValue(selectedItem, getOptionLabel) === getComparisonValue(item, getOptionLabel),
|
|
152
|
+
[styles['item-block--disabled']]: item === null || item === void 0 ? void 0 : item.disabled,
|
|
153
|
+
[styles['item-block--parent']]: hasChildren && !isChild,
|
|
154
|
+
[styles['item-block--child']]: isChild,
|
|
68
155
|
});
|
|
69
|
-
const
|
|
70
|
-
return (React.createElement("div", { className: itemContainerClasses, onClick: handleItemClick },
|
|
156
|
+
const itemContent = (React.createElement("div", { className: itemContainerClasses, onClick: handleItemClick },
|
|
71
157
|
React.createElement("div", { className: itemClassess },
|
|
72
158
|
React.createElement("div", { className: itemBlock },
|
|
73
159
|
variant === 'icons' &&
|
|
@@ -75,14 +161,16 @@ export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedIt
|
|
|
75
161
|
React.cloneElement(item.icon, {
|
|
76
162
|
strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
|
|
77
163
|
}),
|
|
78
|
-
React.createElement("div", { className: styles.item },
|
|
79
|
-
React.createElement("span", null, item
|
|
80
|
-
|
|
164
|
+
React.createElement("div", { className: styles.item, ref: itemRef },
|
|
165
|
+
React.createElement("span", null, getComparisonValue(item, getOptionLabel))),
|
|
166
|
+
!hasChildren &&
|
|
167
|
+
getComparisonValue(selectedItem, getOptionLabel) === getComparisonValue(item, getOptionLabel) && (React.createElement(IconCheck, { strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0', htmlColor: "#0D99FF" }))),
|
|
81
168
|
(item === null || item === void 0 ? void 0 : item.isDivider) && React.createElement("div", { className: styles.divider })),
|
|
82
|
-
|
|
169
|
+
hasChildren && (React.createElement("div", { className: styles.nestedMenu }, (_a = item.children) === null || _a === void 0 ? void 0 : _a.map((child, childIndex) => {
|
|
83
170
|
var _a;
|
|
84
|
-
return (React.createElement(DropdownListItem, { key: (_a = child === null || child === void 0 ? void 0 : child.key) !== null && _a !== void 0 ? _a : childIndex
|
|
171
|
+
return (React.createElement(DropdownListItem, { key: (_a = child === null || child === void 0 ? void 0 : child.key) !== null && _a !== void 0 ? _a : `${index}-${childIndex}`, item: child, getOptionLabel: getOptionLabel, size: size, selectedItem: selectedItem, onChange: onChange, isActive: false, activeIndex: activeIndex, index: childIndex, isChild: true }));
|
|
85
172
|
})))));
|
|
173
|
+
return showTooltip ? (React.createElement(Tooltip, { label: ((_b = getComparisonValue(item, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left" }, itemContent)) : (itemContent);
|
|
86
174
|
};
|
|
87
175
|
export const Dropdown = ({ options, id, label, placeholder, required = false, value, defaultValue, onChange, getOptionLabel, variant = 'text', size = 'lg', style, className, isLeftLabel = false, isDivider = false, disabled = false, readOnly = false, isOpened = false, error = false, helperText, onClick, onBlur, onFocus, onClose, clearable = true, enableAutocomplete = false, noOptionsText = 'Нет вариантов для выбора', }) => {
|
|
88
176
|
const [isOpen, setIsOpen] = useState(isOpened);
|
|
@@ -103,7 +191,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
103
191
|
[styles['dropdown--container-helperText']]: errorInput,
|
|
104
192
|
});
|
|
105
193
|
const buttonClassess = classNames(styles.button, styles[`button--${size}`], {
|
|
106
|
-
[styles['button-item--selected']]: (selectedItem
|
|
194
|
+
[styles['button-item--selected']]: getComparisonValue(selectedItem, getOptionLabel) && !disabled,
|
|
107
195
|
[styles['button--readOnly']]: readOnly,
|
|
108
196
|
[styles['button--disabled']]: disabled,
|
|
109
197
|
[styles['button--error']]: errorInput,
|
|
@@ -142,7 +230,9 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
142
230
|
const newIsOpen = !isOpen;
|
|
143
231
|
setIsOpen(newIsOpen);
|
|
144
232
|
if (newIsOpen && enableAutocomplete) {
|
|
145
|
-
const value = (selectedItem
|
|
233
|
+
const value = getComparisonValue(selectedItem, getOptionLabel)
|
|
234
|
+
? getComparisonValue(selectedItem, getOptionLabel).toString()
|
|
235
|
+
: searchValue;
|
|
146
236
|
setSearchValue(value);
|
|
147
237
|
setFilteredOptions(modifiedOptions);
|
|
148
238
|
requestAnimationFrame(() => {
|
|
@@ -159,7 +249,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
159
249
|
event.preventDefault();
|
|
160
250
|
event.stopPropagation();
|
|
161
251
|
const newEvent = Object.assign(Object.assign({}, event), { currentTarget: Object.assign(Object.assign({}, event.currentTarget), { value: item }) });
|
|
162
|
-
if ((selectedItem
|
|
252
|
+
if (getComparisonValue(selectedItem, getOptionLabel) !== getComparisonValue(item, getOptionLabel)) {
|
|
163
253
|
setSelectedItem(item);
|
|
164
254
|
setIsOpen(false);
|
|
165
255
|
onChange === null || onChange === void 0 ? void 0 : onChange(newEvent, item);
|
|
@@ -191,10 +281,10 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
191
281
|
}
|
|
192
282
|
if (enableAutocomplete &&
|
|
193
283
|
event.target instanceof HTMLInputElement &&
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
284
|
+
event.key !== 'ArrowDown' &&
|
|
285
|
+
event.key !== 'ArrowUp' &&
|
|
286
|
+
event.key !== 'Enter' &&
|
|
287
|
+
event.key !== 'Escape') {
|
|
198
288
|
return;
|
|
199
289
|
}
|
|
200
290
|
switch (event.key) {
|
|
@@ -227,14 +317,12 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
227
317
|
const handleReset = (event) => {
|
|
228
318
|
event.preventDefault();
|
|
229
319
|
event.stopPropagation();
|
|
230
|
-
const startValue = defaultValue
|
|
231
|
-
? checkItem(defaultValue)
|
|
232
|
-
: null;
|
|
320
|
+
const startValue = defaultValue ? checkItem(defaultValue) : null;
|
|
233
321
|
setSelectedItem(startValue !== null && startValue !== void 0 ? startValue : null);
|
|
234
322
|
if (!enableAutocomplete) {
|
|
235
323
|
setIsOpen(false);
|
|
236
324
|
}
|
|
237
|
-
setSearchValue(
|
|
325
|
+
setSearchValue('');
|
|
238
326
|
setFilteredOptions(modifiedOptions);
|
|
239
327
|
onChange === null || onChange === void 0 ? void 0 : onChange(event, startValue !== null && startValue !== void 0 ? startValue : null);
|
|
240
328
|
onClose === null || onClose === void 0 ? void 0 : onClose(event);
|
|
@@ -244,15 +332,29 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
244
332
|
setErrorInputHelperText(helperText !== null && helperText !== void 0 ? helperText : 'Поле обязательно для заполнения');
|
|
245
333
|
}
|
|
246
334
|
};
|
|
335
|
+
const [showSelectedTooltip, setShowSelectedTooltip] = useState(false);
|
|
336
|
+
const selectedItemRef = useRef(null);
|
|
337
|
+
useEffect(() => {
|
|
338
|
+
const checkOverflow = () => {
|
|
339
|
+
setShowSelectedTooltip(isTextOverflowing(selectedItemRef.current));
|
|
340
|
+
};
|
|
341
|
+
checkOverflow();
|
|
342
|
+
window.addEventListener('resize', checkOverflow);
|
|
343
|
+
return () => {
|
|
344
|
+
window.removeEventListener('resize', checkOverflow);
|
|
345
|
+
};
|
|
346
|
+
}, [getComparisonValue(selectedItem, getOptionLabel)]);
|
|
247
347
|
const getTextField = () => {
|
|
248
|
-
var _a;
|
|
249
|
-
|
|
348
|
+
var _a, _b;
|
|
349
|
+
const textFieldContent = (React.createElement("div", { className: selectedItemClassess, ref: selectedItemRef },
|
|
250
350
|
variant === 'icons' &&
|
|
251
351
|
(selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.icon) &&
|
|
252
352
|
React.cloneElement(selectedItem.icon, {
|
|
253
353
|
strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
|
|
254
354
|
}),
|
|
255
|
-
isOpen && enableAutocomplete ? (React.createElement("input", { ref: inputRef, type: "text", value: searchValue, className: styles.inlineSearchInput, onChange: handleSearchChange, placeholder: (selectedItem
|
|
355
|
+
isOpen && enableAutocomplete ? (React.createElement("input", { ref: inputRef, type: "text", value: searchValue, className: styles.inlineSearchInput, onChange: handleSearchChange, placeholder: getComparisonValue(selectedItem, getOptionLabel)
|
|
356
|
+
? getComparisonValue(selectedItem, getOptionLabel).toString()
|
|
357
|
+
: 'Поиск...', onClick: (e) => {
|
|
256
358
|
e.stopPropagation();
|
|
257
359
|
e.preventDefault();
|
|
258
360
|
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
@@ -265,16 +367,16 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
265
367
|
}, onBlur: (e) => {
|
|
266
368
|
e.stopPropagation();
|
|
267
369
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
268
|
-
}, onKeyDown: handleKeyDown, autoFocus: true })) : selectedItem ? (selectedItem
|
|
370
|
+
}, onKeyDown: handleKeyDown, autoFocus: true })) : selectedItem ? (getComparisonValue(selectedItem, getOptionLabel)) : (searchValue || ((_a = placeholder !== null && placeholder !== void 0 ? placeholder : label) !== null && _a !== void 0 ? _a : 'Выберите значение'))));
|
|
371
|
+
return showSelectedTooltip ? (React.createElement("div", { className: styles.textField },
|
|
372
|
+
React.createElement(Tooltip, { label: ((_b = getComparisonValue(selectedItem, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left", style: { width: '100% !important' } }, textFieldContent))) : (textFieldContent);
|
|
269
373
|
};
|
|
270
374
|
const getDropdownMenu = () => {
|
|
271
|
-
const optionsToRender = enableAutocomplete && searchValue
|
|
272
|
-
? filteredOptions
|
|
273
|
-
: modifiedOptions;
|
|
375
|
+
const optionsToRender = enableAutocomplete && searchValue ? filteredOptions : modifiedOptions;
|
|
274
376
|
const menu = isOpen && (React.createElement("div", { className: dropdownClassess }, optionsToRender && optionsToRender.length > 0 ? (optionsToRender.map((optionsToRender, index) => {
|
|
275
377
|
var _a;
|
|
276
378
|
return (React.createElement(DropdownListItem, { key: (_a = optionsToRender === null || optionsToRender === void 0 ? void 0 : optionsToRender.key) !== null && _a !== void 0 ? _a : index, item: optionsToRender, getOptionLabel: getOptionLabel, size: size, selectedItem: selectedItem, variant: variant, onChange: onChangeHandler, isActive: activeIndex === index, activeIndex: activeIndex, index: index }));
|
|
277
|
-
})) : (React.createElement("div", { className: `${styles['item-container']} ${styles['item-block']}`, style: { paddingLeft:
|
|
379
|
+
})) : (React.createElement("div", { className: `${styles['item-container']} ${styles['item-block']}`, style: { paddingLeft: '15px' } }, noOptionsText))));
|
|
278
380
|
return isOpen ? menu : null;
|
|
279
381
|
};
|
|
280
382
|
useEffect(() => {
|
|
@@ -289,13 +391,13 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
289
391
|
const text = (_a = label !== null && label !== void 0 ? label : placeholder) !== null && _a !== void 0 ? _a : '';
|
|
290
392
|
let newWidth;
|
|
291
393
|
if (!isLeftLabel) {
|
|
292
|
-
const textWidth = Math.max((text || '').length, (((_b = selectedItem
|
|
394
|
+
const textWidth = Math.max((text || '').length, (((_b = getComparisonValue(selectedItem, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '').length);
|
|
293
395
|
const inPixel = size === 'lg' ? 11 : 9;
|
|
294
396
|
newWidth = textWidth * inPixel;
|
|
295
397
|
}
|
|
296
398
|
else {
|
|
297
399
|
const inPixel = size === 'lg' ? 11 : 9;
|
|
298
|
-
const selectedValue = ((_c = selectedItem
|
|
400
|
+
const selectedValue = ((_c = getComparisonValue(selectedItem, getOptionLabel)) === null || _c === void 0 ? void 0 : _c.toString()) || '';
|
|
299
401
|
newWidth = (text.length + selectedValue.length) * inPixel + 40;
|
|
300
402
|
}
|
|
301
403
|
setContainerWidth(newWidth);
|
|
@@ -309,7 +411,8 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
309
411
|
if (options) {
|
|
310
412
|
const modifiedOptions = options.map((option, index) => {
|
|
311
413
|
const modifiedOption = checkItem === null || checkItem === void 0 ? void 0 : checkItem(option, getOptionLabel, disabled, isDivider);
|
|
312
|
-
if (modifiedOption &&
|
|
414
|
+
if (modifiedOption &&
|
|
415
|
+
getComparisonValue(modifiedOption, getOptionLabel) === getComparisonValue(selectedItem, getOptionLabel)) {
|
|
313
416
|
setActiveIndex(index);
|
|
314
417
|
}
|
|
315
418
|
return modifiedOption;
|
|
@@ -340,9 +443,10 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
340
443
|
label && (React.createElement(Typography, { variant: "Caption", className: labelClasses }, label)),
|
|
341
444
|
React.createElement("button", { className: buttonClassess, onClick: readOnly ? undefined : handleToggle, disabled: disabled, tabIndex: 0, onKeyDown: handleKeyDown },
|
|
342
445
|
getTextField(),
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
446
|
+
React.createElement("div", { className: styles.actionButtons },
|
|
447
|
+
clearable && !readOnly && !disabled && (selectedItem || (enableAutocomplete && searchValue)) && (React.createElement("div", { className: styles.resetButton },
|
|
448
|
+
React.createElement(IconClose, { strokeWidth: "0.2", htmlColor: "var(--text-light)", onClick: handleReset }))),
|
|
449
|
+
React.createElement("div", { className: styles.dropdownIcon }, !isOpen ? (React.createElement(ChevronDown, { strokeWidth: size === 'lg' ? '0.5' : '0.3' })) : (React.createElement(ChevronUp, { strokeWidth: size === 'lg' ? '0.5' : '0.3' })))),
|
|
346
450
|
getDropdownMenu()),
|
|
347
451
|
errorInput && errorInputHelperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText, styles[size]) }, helperText !== null && helperText !== void 0 ? helperText : errorInputHelperText))));
|
|
348
452
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
.dropdown--container {
|
|
2
2
|
position: relative;
|
|
3
3
|
width: 100%;
|
|
4
|
-
max-width: 260px;
|
|
5
4
|
}
|
|
6
5
|
.dropdown--container-left {
|
|
7
6
|
display: flex;
|
|
@@ -35,17 +34,15 @@
|
|
|
35
34
|
line-height: 16.5px;
|
|
36
35
|
border-radius: 10px;
|
|
37
36
|
cursor: pointer;
|
|
38
|
-
padding:
|
|
37
|
+
padding: 6px 12px;
|
|
39
38
|
transition: all 0.3s ease;
|
|
40
39
|
background-color: transparent;
|
|
41
40
|
color: var(--text-dark);
|
|
42
41
|
border: 1px solid var(--grey-mediumLight);
|
|
43
|
-
/* mix-blend-mode: multiply; */
|
|
44
42
|
display: flex;
|
|
45
43
|
align-items: center;
|
|
46
44
|
gap: 20px;
|
|
47
45
|
justify-content: space-between;
|
|
48
|
-
/* min-width: fit-content; */
|
|
49
46
|
position: relative;
|
|
50
47
|
width: 100%;
|
|
51
48
|
}
|
|
@@ -100,10 +97,15 @@
|
|
|
100
97
|
.button:focus-visible {
|
|
101
98
|
outline: none;
|
|
102
99
|
}
|
|
103
|
-
|
|
100
|
+
.actionButtons {
|
|
101
|
+
display: flex;
|
|
102
|
+
gap: 0px;
|
|
103
|
+
align-items: center;
|
|
104
|
+
margin-right: -6px;
|
|
105
|
+
}
|
|
104
106
|
.resetButton,
|
|
105
107
|
.dropdownIcon {
|
|
106
|
-
position: absolute;
|
|
108
|
+
/* position: absolute; */
|
|
107
109
|
background: none;
|
|
108
110
|
border: none;
|
|
109
111
|
cursor: pointer;
|
|
@@ -143,6 +145,20 @@
|
|
|
143
145
|
overflow-x: hidden;
|
|
144
146
|
}
|
|
145
147
|
|
|
148
|
+
.textField {
|
|
149
|
+
width: 100%;
|
|
150
|
+
overflow: hidden;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.textField > :first-child {
|
|
154
|
+
width: 100%;
|
|
155
|
+
overflow: hidden;
|
|
156
|
+
text-overflow: ellipsis;
|
|
157
|
+
white-space: nowrap;
|
|
158
|
+
min-width: 0;
|
|
159
|
+
display: block;
|
|
160
|
+
}
|
|
161
|
+
|
|
146
162
|
.inlineSearchInput {
|
|
147
163
|
border: none;
|
|
148
164
|
outline: none;
|
|
@@ -157,16 +173,18 @@
|
|
|
157
173
|
}
|
|
158
174
|
|
|
159
175
|
.item--container {
|
|
160
|
-
padding:
|
|
161
|
-
width:
|
|
162
|
-
margin: auto;
|
|
176
|
+
padding: 6px;
|
|
177
|
+
width: 89%;
|
|
178
|
+
/* margin: auto; */
|
|
179
|
+
margin-left: 10px;
|
|
163
180
|
}
|
|
164
181
|
|
|
165
182
|
.item--container:hover,
|
|
166
183
|
.item--container--active {
|
|
167
184
|
background-color: rgba(120, 120, 128, 0.08);
|
|
168
185
|
border-radius: 5px;
|
|
169
|
-
|
|
186
|
+
width: 89%;
|
|
187
|
+
/* margin: auto; */
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
.item-block {
|
|
@@ -255,13 +273,13 @@
|
|
|
255
273
|
|
|
256
274
|
.item-selected {
|
|
257
275
|
color: var(--text-dark);
|
|
258
|
-
width: 80%;
|
|
259
276
|
overflow: hidden;
|
|
260
277
|
text-overflow: ellipsis;
|
|
261
278
|
white-space: nowrap;
|
|
262
279
|
min-width: 0;
|
|
263
280
|
text-align: left;
|
|
264
281
|
position: relative;
|
|
282
|
+
flex: 1;
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
.item-selected .inlineSearchInput {
|
|
@@ -296,3 +314,26 @@
|
|
|
296
314
|
text-overflow: ellipsis;
|
|
297
315
|
color: var(--error-main);
|
|
298
316
|
}
|
|
317
|
+
|
|
318
|
+
/* Стили для родительских элементов */
|
|
319
|
+
.item-block--parent {
|
|
320
|
+
font-weight: 600;
|
|
321
|
+
cursor: default;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.item--container--child {
|
|
325
|
+
width: 100%;
|
|
326
|
+
}
|
|
327
|
+
.item--container--child:hover {
|
|
328
|
+
width: 100%;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* Стили для дочерних элементов */
|
|
332
|
+
.item-block--child {
|
|
333
|
+
font-weight: 400;
|
|
334
|
+
cursor: pointer;
|
|
335
|
+
padding-left: 6px;
|
|
336
|
+
display: grid;
|
|
337
|
+
grid-template-columns: 1fr 20px;
|
|
338
|
+
justify-content: space-between;
|
|
339
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import styles from './Link.module.css';
|
|
4
|
+
export const Link = ({ href, children, title, className, style, underline = 'hover' }) => {
|
|
5
|
+
const stylesUnderline = underline === 'hover' && styles.linkHover;
|
|
6
|
+
return (React.createElement("a", { href: href, title: title, className: classNames(styles.link, stylesUnderline, className), style: style }, children));
|
|
7
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export { ListItem as ListItem } from './components/ListItem/ListItem';
|
|
|
26
26
|
export { Breadcrumb as Breadcrumb } from './components/Breadcrumb/Breadcrumb';
|
|
27
27
|
export { Breadcrumbs as Breadcrumbs } from './components/Breadcrumbs/Breadcrumbs';
|
|
28
28
|
export { Tooltip as Tooltip } from './components/Tooltip/Tooltip';
|
|
29
|
-
export
|
|
29
|
+
export { Link as Link } from './components/Link/Link';
|
|
30
|
+
export type { ButtonProps, InputProps, DateInputProps, TagProps, SettingTagProps, ToggleButtonProps, BaseOptions, TOptions, DropdownProps, TypographyProps, ProgressBarProps, ProgressLoaderProps, RadioProps, TabsProps, ColorPickerProps, SnackbarProps, FileAttachProps, FileListAttaсhedProps, FileItemProps, FileLoaderProps, SpinnerProps, DialogProps, IconButtonProps, BaseListProps, ListProps, ListItemProps, BreadcrumbProps, BreadcrumbsProps, TooltipProps, LinkProps, } from './types';
|
|
30
31
|
import './fonts.css';
|
|
31
32
|
import './colors.css';
|
package/dist/index.js
CHANGED
|
@@ -26,5 +26,6 @@ export { ListItem as ListItem } from './components/ListItem/ListItem';
|
|
|
26
26
|
export { Breadcrumb as Breadcrumb } from './components/Breadcrumb/Breadcrumb';
|
|
27
27
|
export { Breadcrumbs as Breadcrumbs } from './components/Breadcrumbs/Breadcrumbs';
|
|
28
28
|
export { Tooltip as Tooltip } from './components/Tooltip/Tooltip';
|
|
29
|
+
export { Link as Link } from './components/Link/Link';
|
|
29
30
|
import './fonts.css';
|
|
30
31
|
import './colors.css';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -124,6 +124,8 @@ export interface DateInputProps {
|
|
|
124
124
|
onBlur?: React.FocusEventHandler<HTMLElement>;
|
|
125
125
|
/** Обязательное поле */
|
|
126
126
|
required?: boolean;
|
|
127
|
+
/** Язык */
|
|
128
|
+
lng?: string;
|
|
127
129
|
}
|
|
128
130
|
/** @internal */
|
|
129
131
|
export interface TagProps {
|
|
@@ -161,15 +163,7 @@ export interface ToggleButtonProps {
|
|
|
161
163
|
label?: string;
|
|
162
164
|
}
|
|
163
165
|
export type BaseOptions = {
|
|
164
|
-
|
|
165
|
-
key?: string | number;
|
|
166
|
-
name?: string;
|
|
167
|
-
description?: string;
|
|
168
|
-
value?: string | number;
|
|
169
|
-
icon?: React.JSX.Element;
|
|
170
|
-
disabled?: boolean;
|
|
171
|
-
isDivider?: boolean;
|
|
172
|
-
children?: TOptions[];
|
|
166
|
+
[key: string]: any;
|
|
173
167
|
};
|
|
174
168
|
export type TOptions<T = {}> = BaseOptions & T;
|
|
175
169
|
export interface DropdownProps {
|
|
@@ -190,7 +184,7 @@ export interface DropdownProps {
|
|
|
190
184
|
/** Callback, который будет вызван при изменении значения */
|
|
191
185
|
onChange?: (event: any, value: string | number | TOptions | null) => void;
|
|
192
186
|
/** Функция для получения текста опции */
|
|
193
|
-
getOptionLabel?: (option: TOptions) =>
|
|
187
|
+
getOptionLabel?: (option: TOptions) => string;
|
|
194
188
|
/** Вариaнты выпадающего списка(текст + иконка, текст)' */
|
|
195
189
|
variant?: 'icons' | 'text';
|
|
196
190
|
/** Размер */
|
|
@@ -585,3 +579,17 @@ export interface TooltipProps {
|
|
|
585
579
|
/** Подсказка, следующая за курсором */
|
|
586
580
|
followCursor?: boolean;
|
|
587
581
|
}
|
|
582
|
+
export interface LinkProps {
|
|
583
|
+
/**Гипертекстовая ссылка */
|
|
584
|
+
href: string;
|
|
585
|
+
/** Дочерние элементы */
|
|
586
|
+
children: ReactNode;
|
|
587
|
+
/**Заголовок, содержащий дополнительную информацию о ссылке */
|
|
588
|
+
title?: string;
|
|
589
|
+
/** Дополнительный класс */
|
|
590
|
+
className?: string;
|
|
591
|
+
/** Стили передаваемые напрямую */
|
|
592
|
+
style?: CSSProperties;
|
|
593
|
+
/**Подчеркивание */
|
|
594
|
+
underline?: 'hover' | 'underline';
|
|
595
|
+
}
|