kamotive_ui 1.2.23 → 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 +22 -16
- package/dist/components/DateInput/DateInput.module.css +5 -6
- package/dist/components/Dropdown/Dropdown.d.ts +2 -1
- package/dist/components/Dropdown/Dropdown.js +114 -43
- package/dist/components/Dropdown/Dropdown.module.css +30 -5
- 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/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/types/index.d.ts +16 -10
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@ import { ChevronLeft } from '../../Icons/ChevronLeft/ChevronLeft';
|
|
|
13
13
|
import { Button } from '../Button/Button';
|
|
14
14
|
registerLocale('ru', ru);
|
|
15
15
|
registerLocale('en', enUS);
|
|
16
|
-
const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, className, disabled = false, readOnly = false, dateFormat = 'dd.MM.yyyy' }, ref) => {
|
|
16
|
+
const CustomInput = forwardRef(({ value = '', lng, onClick, onDateChange, onClose, className, disabled = false, readOnly = false, dateFormat = 'dd.MM.yyyy' }, ref) => {
|
|
17
17
|
const inputRef = useRef(null);
|
|
18
18
|
const [selectedPart, setSelectedPart] = useState(null);
|
|
19
19
|
const [tempInput, setTempInput] = useState('');
|
|
@@ -26,6 +26,8 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
26
26
|
month: { start: 3, end: 5 },
|
|
27
27
|
year: { start: 6, end: 10 },
|
|
28
28
|
};
|
|
29
|
+
const placeholderText = lng === 'ru' ? 'Не выбрано' : 'Not selected';
|
|
30
|
+
const displayValue = value || placeholderText;
|
|
29
31
|
const selectDatePart = (part) => {
|
|
30
32
|
setSelectedPart(part);
|
|
31
33
|
setTempInput('');
|
|
@@ -52,18 +54,20 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
52
54
|
if (!inputRef.current)
|
|
53
55
|
return;
|
|
54
56
|
setHasFocus(true);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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);
|
|
65
70
|
}
|
|
66
|
-
selectDatePart(newSelectedPart);
|
|
67
71
|
};
|
|
68
72
|
const handleKeyDown = (e) => {
|
|
69
73
|
if (!inputRef.current || !onDateChange || selectedPart === null)
|
|
@@ -166,7 +170,9 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
166
170
|
};
|
|
167
171
|
const handleFocus = () => {
|
|
168
172
|
setHasFocus(true);
|
|
169
|
-
|
|
173
|
+
if (value) {
|
|
174
|
+
selectDatePart('day');
|
|
175
|
+
}
|
|
170
176
|
};
|
|
171
177
|
const handleBlur = () => {
|
|
172
178
|
setHasFocus(false);
|
|
@@ -193,7 +199,7 @@ const CustomInput = forwardRef(({ value = '', onClick, onDateChange, onClose, cl
|
|
|
193
199
|
useImperativeHandle(ref, () => ({
|
|
194
200
|
removeSelection,
|
|
195
201
|
}), [removeSelection]);
|
|
196
|
-
return (React.createElement("input", { ref: inputRef, value: input, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: handleFocus, onBlur: handleBlur, onChange: () => { }, 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 }));
|
|
197
203
|
});
|
|
198
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', }) => {
|
|
199
205
|
const wrapperClassess = classNames(styles['wrapper--input'], className, {
|
|
@@ -212,7 +218,7 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
212
218
|
[styles['label--left']]: isLeftLabel,
|
|
213
219
|
[styles['label--required']]: required,
|
|
214
220
|
});
|
|
215
|
-
const [selectedDate, setSelectedDate] = useState(value ? new Date(value) :
|
|
221
|
+
const [selectedDate, setSelectedDate] = useState(value ? new Date(value) : null);
|
|
216
222
|
const [isMonthPickerOpen, setIsMonthPickerOpen] = useState(false);
|
|
217
223
|
const datePickerRef = useRef(null);
|
|
218
224
|
const inputRef = useRef(null);
|
|
@@ -359,6 +365,6 @@ export const DateInput = ({ id, label = 'Выберите дату', size = 'lg'
|
|
|
359
365
|
: {
|
|
360
366
|
renderCustomHeader: renderCustomHeader,
|
|
361
367
|
renderDayContents: renderDayContents,
|
|
362
|
-
}), { customInput: React.createElement(CustomInput, { ref: inputRef, className: classNames(inputClassess, inputClassName), onDateChange: handleCustomInputChange, onClose: handleCloseDatePicker, disabled: disabled, readOnly: readOnly, dateFormat: dateFormat }) })),
|
|
368
|
+
}), { customInput: React.createElement(CustomInput, { ref: inputRef, lng: lng, className: classNames(inputClassess, inputClassName), onDateChange: handleCustomInputChange, onClose: handleCloseDatePicker, disabled: disabled, readOnly: readOnly, dateFormat: dateFormat }) })),
|
|
363
369
|
error && helperText && (React.createElement(Typography, { variant: "Caption", className: classNames(styles.helperText, styles[size]) }, helperText))));
|
|
364
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>;
|
|
@@ -12,26 +12,79 @@ const isTextOverflowing = (element) => {
|
|
|
12
12
|
return false;
|
|
13
13
|
return element.scrollWidth > element.clientWidth;
|
|
14
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
|
+
};
|
|
15
32
|
function checkItem(item, getOptionLabel, disabled, isDivider) {
|
|
16
33
|
if (typeof item === 'object' && item !== null) {
|
|
17
34
|
const itemCopy = Object.assign({}, item);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
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);
|
|
23
79
|
if (nestedItem) {
|
|
24
80
|
if (!itemCopy.children) {
|
|
25
81
|
itemCopy.children = [];
|
|
26
82
|
}
|
|
27
83
|
itemCopy.children.push(nestedItem);
|
|
28
|
-
|
|
84
|
+
// Заменяем value на обработанное значение
|
|
85
|
+
itemCopy.value = nestedItem.value;
|
|
29
86
|
}
|
|
30
87
|
}
|
|
31
|
-
});
|
|
32
|
-
// проверка на наличие пользовательского поля для вывода(передаваемой функции getOptionLabel)
|
|
33
|
-
if (getOptionLabel) {
|
|
34
|
-
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 });
|
|
35
88
|
}
|
|
36
89
|
if ('value' in itemCopy) {
|
|
37
90
|
return Object.assign(Object.assign({}, itemCopy), { disabled: disabled !== null && disabled !== void 0 ? disabled : false, isDivider: isDivider !== null && isDivider !== void 0 ? isDivider : false });
|
|
@@ -57,7 +110,7 @@ function checkItem(item, getOptionLabel, disabled, isDivider) {
|
|
|
57
110
|
return null;
|
|
58
111
|
}
|
|
59
112
|
}
|
|
60
|
-
export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedItem, variant, onChange, isActive, activeIndex, index, }) => {
|
|
113
|
+
export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedItem, variant, onChange, isActive, activeIndex, index, isChild = false, }) => {
|
|
61
114
|
var _a, _b;
|
|
62
115
|
const itemRef = useRef(null);
|
|
63
116
|
const [showTooltip, setShowTooltip] = useState(false);
|
|
@@ -70,20 +123,36 @@ export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedIt
|
|
|
70
123
|
return () => {
|
|
71
124
|
window.removeEventListener('resize', checkOverflow);
|
|
72
125
|
};
|
|
73
|
-
}, [item
|
|
126
|
+
}, [getComparisonValue(item, getOptionLabel)]);
|
|
74
127
|
const handleItemClick = useCallback((event) => {
|
|
75
128
|
event.preventDefault();
|
|
76
129
|
event.stopPropagation();
|
|
77
130
|
if (!(item === null || item === void 0 ? void 0 : item.disabled)) {
|
|
78
|
-
|
|
131
|
+
if (!(item === null || item === void 0 ? void 0 : item.children) || item.children.length === 0) {
|
|
132
|
+
onChange(event, item); // Если у элемента есть дети, не выбираем родительский элемент
|
|
133
|
+
}
|
|
79
134
|
}
|
|
80
135
|
}, [item, onChange]);
|
|
81
|
-
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
|
+
});
|
|
82
142
|
const itemClassess = classNames(styles[`item-block`], styles[`button--${size}`], {
|
|
83
143
|
[styles['item-block--disabled']]: item === null || item === void 0 ? void 0 : item.disabled,
|
|
84
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,
|
|
85
155
|
});
|
|
86
|
-
const itemBlock = classNames(styles[`item-block`], styles[`item-block-${variant}`], { [styles[`item-block-${variant}--selected`]]: (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value) === (item === null || item === void 0 ? void 0 : item.value) }, { [styles['item-block--disabled']]: item === null || item === void 0 ? void 0 : item.disabled });
|
|
87
156
|
const itemContent = (React.createElement("div", { className: itemContainerClasses, onClick: handleItemClick },
|
|
88
157
|
React.createElement("div", { className: itemClassess },
|
|
89
158
|
React.createElement("div", { className: itemBlock },
|
|
@@ -93,14 +162,15 @@ export const DropdownListItem = ({ item, getOptionLabel, size = 'md', selectedIt
|
|
|
93
162
|
strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
|
|
94
163
|
}),
|
|
95
164
|
React.createElement("div", { className: styles.item, ref: itemRef },
|
|
96
|
-
React.createElement("span", null, item
|
|
97
|
-
|
|
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" }))),
|
|
98
168
|
(item === null || item === void 0 ? void 0 : item.isDivider) && React.createElement("div", { className: styles.divider })),
|
|
99
|
-
|
|
169
|
+
hasChildren && (React.createElement("div", { className: styles.nestedMenu }, (_a = item.children) === null || _a === void 0 ? void 0 : _a.map((child, childIndex) => {
|
|
100
170
|
var _a;
|
|
101
|
-
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 }));
|
|
102
172
|
})))));
|
|
103
|
-
return showTooltip ? (React.createElement(Tooltip, { label: ((_b = item
|
|
173
|
+
return showTooltip ? (React.createElement(Tooltip, { label: ((_b = getComparisonValue(item, getOptionLabel)) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left" }, itemContent)) : (itemContent);
|
|
104
174
|
};
|
|
105
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 = 'Нет вариантов для выбора', }) => {
|
|
106
176
|
const [isOpen, setIsOpen] = useState(isOpened);
|
|
@@ -121,7 +191,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
121
191
|
[styles['dropdown--container-helperText']]: errorInput,
|
|
122
192
|
});
|
|
123
193
|
const buttonClassess = classNames(styles.button, styles[`button--${size}`], {
|
|
124
|
-
[styles['button-item--selected']]: (selectedItem
|
|
194
|
+
[styles['button-item--selected']]: getComparisonValue(selectedItem, getOptionLabel) && !disabled,
|
|
125
195
|
[styles['button--readOnly']]: readOnly,
|
|
126
196
|
[styles['button--disabled']]: disabled,
|
|
127
197
|
[styles['button--error']]: errorInput,
|
|
@@ -160,7 +230,9 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
160
230
|
const newIsOpen = !isOpen;
|
|
161
231
|
setIsOpen(newIsOpen);
|
|
162
232
|
if (newIsOpen && enableAutocomplete) {
|
|
163
|
-
const value = (selectedItem
|
|
233
|
+
const value = getComparisonValue(selectedItem, getOptionLabel)
|
|
234
|
+
? getComparisonValue(selectedItem, getOptionLabel).toString()
|
|
235
|
+
: searchValue;
|
|
164
236
|
setSearchValue(value);
|
|
165
237
|
setFilteredOptions(modifiedOptions);
|
|
166
238
|
requestAnimationFrame(() => {
|
|
@@ -177,7 +249,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
177
249
|
event.preventDefault();
|
|
178
250
|
event.stopPropagation();
|
|
179
251
|
const newEvent = Object.assign(Object.assign({}, event), { currentTarget: Object.assign(Object.assign({}, event.currentTarget), { value: item }) });
|
|
180
|
-
if ((selectedItem
|
|
252
|
+
if (getComparisonValue(selectedItem, getOptionLabel) !== getComparisonValue(item, getOptionLabel)) {
|
|
181
253
|
setSelectedItem(item);
|
|
182
254
|
setIsOpen(false);
|
|
183
255
|
onChange === null || onChange === void 0 ? void 0 : onChange(newEvent, item);
|
|
@@ -209,10 +281,10 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
209
281
|
}
|
|
210
282
|
if (enableAutocomplete &&
|
|
211
283
|
event.target instanceof HTMLInputElement &&
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
284
|
+
event.key !== 'ArrowDown' &&
|
|
285
|
+
event.key !== 'ArrowUp' &&
|
|
286
|
+
event.key !== 'Enter' &&
|
|
287
|
+
event.key !== 'Escape') {
|
|
216
288
|
return;
|
|
217
289
|
}
|
|
218
290
|
switch (event.key) {
|
|
@@ -245,14 +317,12 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
245
317
|
const handleReset = (event) => {
|
|
246
318
|
event.preventDefault();
|
|
247
319
|
event.stopPropagation();
|
|
248
|
-
const startValue = defaultValue
|
|
249
|
-
? checkItem(defaultValue)
|
|
250
|
-
: null;
|
|
320
|
+
const startValue = defaultValue ? checkItem(defaultValue) : null;
|
|
251
321
|
setSelectedItem(startValue !== null && startValue !== void 0 ? startValue : null);
|
|
252
322
|
if (!enableAutocomplete) {
|
|
253
323
|
setIsOpen(false);
|
|
254
324
|
}
|
|
255
|
-
setSearchValue(
|
|
325
|
+
setSearchValue('');
|
|
256
326
|
setFilteredOptions(modifiedOptions);
|
|
257
327
|
onChange === null || onChange === void 0 ? void 0 : onChange(event, startValue !== null && startValue !== void 0 ? startValue : null);
|
|
258
328
|
onClose === null || onClose === void 0 ? void 0 : onClose(event);
|
|
@@ -273,7 +343,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
273
343
|
return () => {
|
|
274
344
|
window.removeEventListener('resize', checkOverflow);
|
|
275
345
|
};
|
|
276
|
-
}, [selectedItem
|
|
346
|
+
}, [getComparisonValue(selectedItem, getOptionLabel)]);
|
|
277
347
|
const getTextField = () => {
|
|
278
348
|
var _a, _b;
|
|
279
349
|
const textFieldContent = (React.createElement("div", { className: selectedItemClassess, ref: selectedItemRef },
|
|
@@ -282,7 +352,9 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
282
352
|
React.cloneElement(selectedItem.icon, {
|
|
283
353
|
strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0',
|
|
284
354
|
}),
|
|
285
|
-
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) => {
|
|
286
358
|
e.stopPropagation();
|
|
287
359
|
e.preventDefault();
|
|
288
360
|
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
@@ -295,18 +367,16 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
295
367
|
}, onBlur: (e) => {
|
|
296
368
|
e.stopPropagation();
|
|
297
369
|
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
298
|
-
}, 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 : 'Выберите значение'))));
|
|
299
371
|
return showSelectedTooltip ? (React.createElement("div", { className: styles.textField },
|
|
300
|
-
React.createElement(Tooltip, { label: ((_b = selectedItem
|
|
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);
|
|
301
373
|
};
|
|
302
374
|
const getDropdownMenu = () => {
|
|
303
|
-
const optionsToRender = enableAutocomplete && searchValue
|
|
304
|
-
? filteredOptions
|
|
305
|
-
: modifiedOptions;
|
|
375
|
+
const optionsToRender = enableAutocomplete && searchValue ? filteredOptions : modifiedOptions;
|
|
306
376
|
const menu = isOpen && (React.createElement("div", { className: dropdownClassess }, optionsToRender && optionsToRender.length > 0 ? (optionsToRender.map((optionsToRender, index) => {
|
|
307
377
|
var _a;
|
|
308
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 }));
|
|
309
|
-
})) : (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))));
|
|
310
380
|
return isOpen ? menu : null;
|
|
311
381
|
};
|
|
312
382
|
useEffect(() => {
|
|
@@ -321,13 +391,13 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
321
391
|
const text = (_a = label !== null && label !== void 0 ? label : placeholder) !== null && _a !== void 0 ? _a : '';
|
|
322
392
|
let newWidth;
|
|
323
393
|
if (!isLeftLabel) {
|
|
324
|
-
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);
|
|
325
395
|
const inPixel = size === 'lg' ? 11 : 9;
|
|
326
396
|
newWidth = textWidth * inPixel;
|
|
327
397
|
}
|
|
328
398
|
else {
|
|
329
399
|
const inPixel = size === 'lg' ? 11 : 9;
|
|
330
|
-
const selectedValue = ((_c = selectedItem
|
|
400
|
+
const selectedValue = ((_c = getComparisonValue(selectedItem, getOptionLabel)) === null || _c === void 0 ? void 0 : _c.toString()) || '';
|
|
331
401
|
newWidth = (text.length + selectedValue.length) * inPixel + 40;
|
|
332
402
|
}
|
|
333
403
|
setContainerWidth(newWidth);
|
|
@@ -341,7 +411,8 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
341
411
|
if (options) {
|
|
342
412
|
const modifiedOptions = options.map((option, index) => {
|
|
343
413
|
const modifiedOption = checkItem === null || checkItem === void 0 ? void 0 : checkItem(option, getOptionLabel, disabled, isDivider);
|
|
344
|
-
if (modifiedOption &&
|
|
414
|
+
if (modifiedOption &&
|
|
415
|
+
getComparisonValue(modifiedOption, getOptionLabel) === getComparisonValue(selectedItem, getOptionLabel)) {
|
|
345
416
|
setActiveIndex(index);
|
|
346
417
|
}
|
|
347
418
|
return modifiedOption;
|
|
@@ -373,7 +444,7 @@ export const Dropdown = ({ options, id, label, placeholder, required = false, va
|
|
|
373
444
|
React.createElement("button", { className: buttonClassess, onClick: readOnly ? undefined : handleToggle, disabled: disabled, tabIndex: 0, onKeyDown: handleKeyDown },
|
|
374
445
|
getTextField(),
|
|
375
446
|
React.createElement("div", { className: styles.actionButtons },
|
|
376
|
-
clearable && !readOnly && !disabled && (selectedItem || enableAutocomplete && searchValue) && (React.createElement("div", { className: styles.resetButton },
|
|
447
|
+
clearable && !readOnly && !disabled && (selectedItem || (enableAutocomplete && searchValue)) && (React.createElement("div", { className: styles.resetButton },
|
|
377
448
|
React.createElement(IconClose, { strokeWidth: "0.2", htmlColor: "var(--text-light)", onClick: handleReset }))),
|
|
378
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' })))),
|
|
379
450
|
getDropdownMenu()),
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
overflow-x: hidden;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
.textField{
|
|
148
|
+
.textField {
|
|
149
149
|
width: 100%;
|
|
150
150
|
overflow: hidden;
|
|
151
151
|
}
|
|
@@ -173,16 +173,18 @@
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
.item--container {
|
|
176
|
-
padding:
|
|
177
|
-
width:
|
|
178
|
-
margin: auto;
|
|
176
|
+
padding: 6px;
|
|
177
|
+
width: 89%;
|
|
178
|
+
/* margin: auto; */
|
|
179
|
+
margin-left: 10px;
|
|
179
180
|
}
|
|
180
181
|
|
|
181
182
|
.item--container:hover,
|
|
182
183
|
.item--container--active {
|
|
183
184
|
background-color: rgba(120, 120, 128, 0.08);
|
|
184
185
|
border-radius: 5px;
|
|
185
|
-
|
|
186
|
+
width: 89%;
|
|
187
|
+
/* margin: auto; */
|
|
186
188
|
}
|
|
187
189
|
|
|
188
190
|
.item-block {
|
|
@@ -312,3 +314,26 @@
|
|
|
312
314
|
text-overflow: ellipsis;
|
|
313
315
|
color: var(--error-main);
|
|
314
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
|
@@ -163,15 +163,7 @@ export interface ToggleButtonProps {
|
|
|
163
163
|
label?: string;
|
|
164
164
|
}
|
|
165
165
|
export type BaseOptions = {
|
|
166
|
-
|
|
167
|
-
key?: string | number;
|
|
168
|
-
name?: string;
|
|
169
|
-
description?: string;
|
|
170
|
-
value?: string | number;
|
|
171
|
-
icon?: React.JSX.Element;
|
|
172
|
-
disabled?: boolean;
|
|
173
|
-
isDivider?: boolean;
|
|
174
|
-
children?: TOptions[];
|
|
166
|
+
[key: string]: any;
|
|
175
167
|
};
|
|
176
168
|
export type TOptions<T = {}> = BaseOptions & T;
|
|
177
169
|
export interface DropdownProps {
|
|
@@ -192,7 +184,7 @@ export interface DropdownProps {
|
|
|
192
184
|
/** Callback, который будет вызван при изменении значения */
|
|
193
185
|
onChange?: (event: any, value: string | number | TOptions | null) => void;
|
|
194
186
|
/** Функция для получения текста опции */
|
|
195
|
-
getOptionLabel?: (option: TOptions) =>
|
|
187
|
+
getOptionLabel?: (option: TOptions) => string;
|
|
196
188
|
/** Вариaнты выпадающего списка(текст + иконка, текст)' */
|
|
197
189
|
variant?: 'icons' | 'text';
|
|
198
190
|
/** Размер */
|
|
@@ -587,3 +579,17 @@ export interface TooltipProps {
|
|
|
587
579
|
/** Подсказка, следующая за курсором */
|
|
588
580
|
followCursor?: boolean;
|
|
589
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
|
+
}
|