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.
@@ -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
- const cursorPosition = inputRef.current.selectionStart || 0;
56
- let newSelectedPart;
57
- if (cursorPosition <= positions.day.end) {
58
- newSelectedPart = 'day';
59
- }
60
- else if (cursorPosition <= positions.month.end) {
61
- newSelectedPart = 'month';
62
- }
63
- else {
64
- newSelectedPart = 'year';
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
- selectDatePart('day');
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) : new Date());
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 .lg {
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 .sm {
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 .md {
117
+ .label--left.md {
119
118
  font-size: 12px;
120
119
  }
121
120
 
122
- .label--left .sm {
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?: ((option: TOptions) => string);
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
- Object.keys(itemCopy).forEach((key) => {
20
- const value = itemCopy[key];
21
- if (typeof value === 'object' && value !== null && !React.isValidElement(value)) {
22
- const nestedItem = checkItem(value, getOptionLabel, disabled, isDivider);
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
- delete itemCopy[key];
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 === null || item === void 0 ? void 0 : item.value]);
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
- onChange(event, item);
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 itemContainerClasses = classNames(styles[`item--container`], { [styles['item--container--active']]: isActive });
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 === null || item === void 0 ? void 0 : item.value)),
97
- (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value) === (item === null || item === void 0 ? void 0 : item.value) && (React.createElement(IconCheck, { strokeWidth: size === 'lg' ? '0.5' : size === 'md' ? '0.3' : '0.0', htmlColor: "#0D99FF" }))),
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
- (item === null || item === void 0 ? void 0 : item.children) && (React.createElement("div", { className: styles.nestedMenu }, (_a = item.children) === null || _a === void 0 ? void 0 : _a.map((child, childIndex) => {
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, item: child, getOptionLabel: getOptionLabel, size: size, selectedItem: selectedItem, onChange: onChange, isActive: activeIndex === index, activeIndex: activeIndex, index: 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 === null || item === void 0 ? void 0 : item.value) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left" }, itemContent)) : (itemContent);
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) && !disabled,
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) ? selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value.toString() : searchValue;
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) !== (item === null || item === void 0 ? void 0 : item.value)) {
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
- (event.key !== 'ArrowDown' &&
213
- event.key !== 'ArrowUp' &&
214
- event.key !== 'Enter' &&
215
- event.key !== 'Escape')) {
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value]);
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) ? selectedItem.value.toString() : 'Поиск...', onClick: (e) => {
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.value) : (searchValue || ((_a = placeholder !== null && placeholder !== void 0 ? placeholder : label) !== null && _a !== void 0 ? _a : 'Выберите значение'))));
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) === null || _b === void 0 ? void 0 : _b.toString()) || '', position: "bottom-left", style: { width: '100% !important' } }, textFieldContent))) : (textFieldContent);
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: "15px" } }, noOptionsText))));
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) === null || _b === void 0 ? void 0 : _b.toString()) || '').length);
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 === null || selectedItem === void 0 ? void 0 : selectedItem.value) === null || _c === void 0 ? void 0 : _c.toString()) || '';
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 && modifiedOption.value === (selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.value)) {
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: 0.5em 0.5em;
177
- width: 87%;
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
- margin: auto;
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,3 @@
1
+ import { FC } from 'react';
2
+ import { LinkProps } from '../../types';
3
+ export declare const Link: FC<LinkProps>;
@@ -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
+ };
@@ -0,0 +1,11 @@
1
+ .link {
2
+ color: var(--text-dark)
3
+ }
4
+
5
+ .linkHover {
6
+ text-decoration: none;
7
+ }
8
+
9
+ .linkHover:hover {
10
+ text-decoration: underline;
11
+ }
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 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, } from './types';
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';
@@ -163,15 +163,7 @@ export interface ToggleButtonProps {
163
163
  label?: string;
164
164
  }
165
165
  export type BaseOptions = {
166
- id?: string;
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) => keyof 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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kamotive_ui",
3
- "version": "1.2.23",
3
+ "version": "1.2.24",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [