@ozen-ui/kit 0.32.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/__inner__/cjs/components/DataList/DataList.js +42 -47
  2. package/__inner__/cjs/components/DataList/components/DataListCheckIcon/DataListCheckIcon.css +1 -0
  3. package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.css +19 -6
  4. package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.d.ts +0 -2
  5. package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.js +2 -2
  6. package/__inner__/cjs/components/DataList/helpers/useDataListNavigation.d.ts +3 -6
  7. package/__inner__/cjs/components/DataList/helpers/useDataListNavigation.js +44 -48
  8. package/__inner__/cjs/components/Popover/Popover.js +8 -7
  9. package/__inner__/cjs/components/Popover/constants.d.ts +2 -0
  10. package/__inner__/cjs/components/Popover/constants.js +3 -1
  11. package/__inner__/cjs/components/Popover/types.d.ts +6 -0
  12. package/__inner__/cjs/components/Popover/types.js +2 -1
  13. package/__inner__/cjs/components/Tooltip/Tooltip.js +1 -1
  14. package/__inner__/cjs/hooks/useHover/useHover.d.ts +2 -2
  15. package/__inner__/cjs/hooks/useHover/useHover.js +2 -2
  16. package/__inner__/esm/components/DataList/DataList.js +42 -47
  17. package/__inner__/esm/components/DataList/components/DataListCheckIcon/DataListCheckIcon.css +1 -0
  18. package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.css +19 -6
  19. package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.d.ts +0 -2
  20. package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.js +2 -2
  21. package/__inner__/esm/components/DataList/helpers/useDataListNavigation.d.ts +3 -6
  22. package/__inner__/esm/components/DataList/helpers/useDataListNavigation.js +45 -49
  23. package/__inner__/esm/components/Popover/Popover.js +9 -8
  24. package/__inner__/esm/components/Popover/constants.d.ts +2 -0
  25. package/__inner__/esm/components/Popover/constants.js +2 -0
  26. package/__inner__/esm/components/Popover/types.d.ts +6 -0
  27. package/__inner__/esm/components/Popover/types.js +1 -0
  28. package/__inner__/esm/components/Tooltip/Tooltip.js +1 -1
  29. package/__inner__/esm/hooks/useHover/useHover.d.ts +2 -2
  30. package/__inner__/esm/hooks/useHover/useHover.js +2 -2
  31. package/package.json +1 -1
@@ -32,6 +32,7 @@ var DataListRender = function (inProps, ref) {
32
32
  state: 'selected',
33
33
  }), 2), selectedState = _g[0], setSelected = _g[1];
34
34
  var nodes = (0, react_1.useMemo)(function () { return new Map(); }, [children]);
35
+ var items = (0, react_1.useMemo)(function () { return new Array(); }, [children]);
35
36
  var resolvedChildren = (0, react_is_1.isFragment)(children)
36
37
  ? children.props.children
37
38
  : children;
@@ -40,11 +41,14 @@ var DataListRender = function (inProps, ref) {
40
41
  child.type !== index_1.DataListOption ||
41
42
  !!child.props.disabled;
42
43
  };
43
- react_1.Children.forEach(resolvedChildren, function (child, idx) {
44
- if (!isNotSelectOption(child)) {
45
- nodes.set(child.props.value, idx);
46
- }
47
- });
44
+ (0, react_1.useEffect)(function () {
45
+ react_1.Children.forEach(resolvedChildren, function (child, idx) {
46
+ if (!isNotSelectOption(child)) {
47
+ items.push(child.props.value);
48
+ nodes.set(child.props.value, idx);
49
+ }
50
+ });
51
+ }, [children]);
48
52
  var handleSelect = function (event, value) {
49
53
  var params = {
50
54
  multiple: inProps.multiple,
@@ -53,10 +57,10 @@ var DataListRender = function (inProps, ref) {
53
57
  setSelected: setSelected,
54
58
  };
55
59
  if ((0, helpers_1.isMultipleParams)(params)) {
56
- var selected_1 = params.selected, onSelect = params.onSelect, setSelected_1 = params.setSelected;
57
- var res = (selected_1 === null || selected_1 === void 0 ? void 0 : selected_1.includes(value || ''))
58
- ? selected_1.filter(function (item) { return item !== value; })
59
- : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((selected_1 || [])), false), [value], false);
60
+ var selected = params.selected, onSelect = params.onSelect, setSelected_1 = params.setSelected;
61
+ var res = (selected === null || selected === void 0 ? void 0 : selected.includes(value || ''))
62
+ ? selected.filter(function (item) { return item !== value; })
63
+ : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((selected || [])), false), [value], false);
60
64
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(event, { name: name, value: res });
61
65
  setSelected_1(res);
62
66
  }
@@ -69,24 +73,24 @@ var DataListRender = function (inProps, ref) {
69
73
  // Навигация по списку
70
74
  var _h = (0, helpers_1.useDataListNavigation)({
71
75
  active: opened,
72
- items: tslib_1.__spreadArray([], tslib_1.__read(nodes.keys()), false),
73
- current: (0, helpers_1.lastSelectedValue)(selectedState),
76
+ items: items,
77
+ selected: (0, helpers_1.lastSelectedValue)(selectedState),
74
78
  onSelect: function (event, item) {
75
79
  handleSelect(event, item || '');
76
80
  },
77
- }), selected = _h.selected, focused = _h.focused, highlighted = _h.highlighted, onKeyDown = _h.onKeyDown, onClick = _h.onClick, onMouseEnter = _h.onMouseEnter, onMouseLeave = _h.onMouseLeave;
81
+ }), current = _h.current, focused = _h.focused, onKeyDown = _h.onKeyDown, onClick = _h.onClick;
78
82
  var _j = tslib_1.__read((0, react_1.useState)({ current: null }), 2), selectedElRef = _j[0], setSelectedElRef = _j[1];
79
- // Находит элемент по ключу
80
83
  (0, react_1.useEffect)(function () {
81
84
  var _a, _b;
82
- var current = focused || selected || '';
83
- var idx = nodes.get(current);
85
+ var selected = focused || current || '';
86
+ // Находит элемент по ключу
87
+ var idx = nodes.get(selected);
84
88
  if (idx !== undefined) {
85
89
  setSelectedElRef({
86
90
  current: (_b = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b[idx],
87
91
  });
88
92
  }
89
- }, [focused, selected]);
93
+ }, [focused, current]);
90
94
  // Прокрутка списка
91
95
  (0, helpers_1.useScrollContainerToElement)(dataListRef, selectedElRef, focused ? 'smooth' : 'instant');
92
96
  // Назначает элементу контроля событие управления списком с клавиатуры
@@ -109,37 +113,28 @@ var DataListRender = function (inProps, ref) {
109
113
  },
110
114
  });
111
115
  // Представление раскрывающегося списка
112
- var renderChildren = react_1.Children.map(resolvedChildren, function (child) {
113
- if (isNotSelectOption(child)) {
114
- return child;
115
- }
116
- var key = child.props.value;
117
- var elementChild = child;
118
- var props = {
119
- onClick: function (event) {
120
- var _a, _b;
121
- onClick === null || onClick === void 0 ? void 0 : onClick(event, key);
122
- (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
123
- },
124
- onMouseEnter: function (event) {
125
- var _a, _b;
126
- onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(key);
127
- (_b = (_a = child.props).onMouseEnter) === null || _b === void 0 ? void 0 : _b.call(_a, event);
128
- },
129
- onMouseLeave: function (event) {
130
- var _a, _b;
131
- onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave();
132
- (_b = (_a = child.props).onMouseLeave) === null || _b === void 0 ? void 0 : _b.call(_a, event);
133
- },
134
- highlighted: key === highlighted,
135
- focused: key === focused,
136
- selected: Array.isArray(selectedState)
137
- ? selectedState.includes(key)
138
- : selectedState === key,
139
- };
140
- return (0, react_1.cloneElement)(elementChild, tslib_1.__assign({}, props));
141
- });
142
- return (react_1.default.createElement(Popover_1.Popover, tslib_1.__assign({ as: as, open: open, placement: "bottom-start", disableReturnFocus: true, disableEnforceFocus: true, offset: [0, 4], onClose: onClose, anchorRef: anchorRef, className: (0, exports.cnDataList)('', [className]), transitionProps: {
116
+ var renderChildren = (0, react_1.useMemo)(function () {
117
+ return react_1.Children.map(resolvedChildren, function (child) {
118
+ if (isNotSelectOption(child)) {
119
+ return child;
120
+ }
121
+ var key = child.props.value;
122
+ var elementChild = child;
123
+ var props = {
124
+ onClick: function (event) {
125
+ var _a, _b;
126
+ onClick === null || onClick === void 0 ? void 0 : onClick(event, key);
127
+ (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
128
+ },
129
+ focused: key === focused,
130
+ selected: Array.isArray(selectedState)
131
+ ? selectedState.includes(key)
132
+ : selectedState === key,
133
+ };
134
+ return (0, react_1.cloneElement)(elementChild, props);
135
+ });
136
+ }, [resolvedChildren, selectedState, focused, onClick]);
137
+ return (react_1.default.createElement(Popover_1.Popover, tslib_1.__assign({ as: as, open: open, placement: "bottom-start", strategy: "absolute", disableReturnFocus: true, disableEnforceFocus: true, offset: [0, 4], onClose: onClose, anchorRef: anchorRef, className: (0, exports.cnDataList)('', [className]), transitionProps: {
143
138
  classNames: 'DataList-animation',
144
139
  } }, other, { onEntered: function () {
145
140
  onEntered();
@@ -2,6 +2,7 @@
2
2
  inline-size: var(--data-list-check-icon-size);
3
3
  block-size: var(--data-list-check-icon-size);
4
4
  display: flex;
5
+ flex-shrink: 0;
5
6
  }
6
7
 
7
8
  .DataListCheckIcon_size_s {
@@ -1,20 +1,33 @@
1
1
  .DataListOption {
2
2
  cursor: pointer;
3
+ transition: background-color var(--transition-default);
3
4
  }
4
5
 
5
- .DataListOption_focused {
6
- box-shadow: inset var(--shadow-outline-focused);
6
+ .DataListOption:hover {
7
+ background-color: var(--color-background-main-hover);
7
8
  }
8
9
 
9
- .DataListOption_highlighted {
10
- background-color: var(--color-background-main-hover);
10
+ .DataListOption:active {
11
+ background-color: var(--color-background-main-pressed);
11
12
  }
12
13
 
13
- .DataListOption_disabled {
14
+ .DataListOption_focused {
15
+ box-shadow: inset var(--shadow-outline-focused);
16
+ }
17
+
18
+ .DataListOption_disabled,
19
+ .DataListOption_disabled:hover,
20
+ .DataListOption_disabled:active {
14
21
  cursor: not-allowed;
22
+
23
+ background-color: unset;
15
24
  }
16
25
 
17
26
  .DataListOption_disabled .ListItemText-TextPrimary,
18
- .DataListOption_disabled .ListItemText-TextSecondary {
27
+ .DataListOption_disabled .ListItemText-TextSecondary,
28
+ .DataListOption_disabled:hover .ListItemText-TextPrimary,
29
+ .DataListOption_disabled:hover .ListItemText-TextSecondary,
30
+ .DataListOption_disabled:active .ListItemText-TextPrimary,
31
+ .DataListOption_disabled:active .ListItemText-TextSecondary {
19
32
  color: var(--color-content-tertiary);
20
33
  }
@@ -12,8 +12,6 @@ export type DataListOptionProps = {
12
12
  disabled?: boolean;
13
13
  /** Если {true} отображает опцию сфокусированной (клавиатура) */
14
14
  focused?: boolean;
15
- /** Если {true} отображает опцию наведенной (мышь) */
16
- highlighted?: boolean;
17
15
  /** Если {true} отображает опцию выбранной */
18
16
  selected?: boolean;
19
17
  /** Функция обратного вызова обработчик нажатий на клавиатуре */
@@ -21,7 +21,7 @@ var DataListContent = function (_a) {
21
21
  react_1.default.createElement(DataListCheckIcon_1.DataListCheckIcon, { selected: selected, size: iconSize })));
22
22
  };
23
23
  exports.DataListOption = (0, react_1.forwardRef)(function (_a, ref) {
24
- var _b = _a.disabled, disabled = _b === void 0 ? constants_1.DATA_LIST_OPTION_DEFAULT_DISABLED : _b, value = _a.value, label = _a.label, children = _a.children, className = _a.className, highlighted = _a.highlighted, selected = _a.selected, focused = _a.focused, other = tslib_1.__rest(_a, ["disabled", "value", "label", "children", "className", "highlighted", "selected", "focused"]);
24
+ var _b = _a.disabled, disabled = _b === void 0 ? constants_1.DATA_LIST_OPTION_DEFAULT_DISABLED : _b, value = _a.value, label = _a.label, children = _a.children, className = _a.className, selected = _a.selected, focused = _a.focused, other = tslib_1.__rest(_a, ["disabled", "value", "label", "children", "className", "selected", "focused"]);
25
25
  var renderChildren = function () {
26
26
  if ((0, isString_1.isString)(children) || (0, isNumber_1.isNumber)(children)) {
27
27
  return react_1.default.createElement(DataListContent, { label: children, selected: selected });
@@ -33,7 +33,7 @@ exports.DataListOption = (0, react_1.forwardRef)(function (_a, ref) {
33
33
  };
34
34
  return (react_1.default.createElement(List_1.ListItem, tslib_1.__assign({ role: "option", "aria-selected": selected, "aria-disabled": disabled, "data-label": label, "data-value": value, className: (0, exports.cnDataListOption)({
35
35
  disabled: disabled,
36
- highlighted: !disabled && highlighted,
36
+ selected: selected,
37
37
  focused: !disabled && focused,
38
38
  }, [className]) }, other, { ref: ref }), renderChildren()));
39
39
  });
@@ -4,20 +4,17 @@ export type UseListNavigationItems = UseListNavigationItem[];
4
4
  export type UseListNavigationProps = {
5
5
  active?: boolean;
6
6
  items?: UseListNavigationItems;
7
- current?: UseListNavigationItem;
7
+ selected?: UseListNavigationItem;
8
8
  onSelect?: (event: KeyboardEvent | MouseEvent<HTMLElement>, item?: UseListNavigationItem) => void;
9
9
  };
10
10
  export type UseListNavigationState = {
11
11
  focused?: UseListNavigationItem;
12
- selected?: UseListNavigationItem;
13
- highlighted?: UseListNavigationItem;
12
+ current?: UseListNavigationItem;
14
13
  };
15
14
  export type UseListNavigationEvents = {
16
- onMouseLeave?: () => void;
17
15
  onKeyDown?: (event: KeyboardEvent) => void;
18
16
  onClick?: (event: MouseEvent<HTMLElement>, item: UseListNavigationItem) => void;
19
- onMouseEnter?: (item: UseListNavigationItem) => void;
20
17
  };
21
18
  export type UseListNavigationReturn = UseListNavigationState & UseListNavigationEvents;
22
19
  /** Навигация по элементам списка без перехвата фокуса с элемента контроля */
23
- export declare function useDataListNavigation({ current, onSelect, active, items: itemsProps, }: UseListNavigationProps): UseListNavigationReturn;
20
+ export declare function useDataListNavigation({ selected, onSelect, active, items: itemsProps, }: UseListNavigationProps): UseListNavigationReturn;
@@ -6,83 +6,79 @@ var react_1 = require("react");
6
6
  var getNextIndex_1 = require("../../../utils/getNextIndex");
7
7
  var getPrevIndex_1 = require("../../../utils/getPrevIndex");
8
8
  var isKey_1 = require("../../../utils/isKey");
9
+ var isKeys_1 = require("../../../utils/isKeys");
9
10
  /** Навигация по элементам списка без перехвата фокуса с элемента контроля */
10
11
  function useDataListNavigation(_a) {
11
- var current = _a.current, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
12
+ var selected = _a.selected, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
12
13
  var savedItems = (0, react_1.useRef)(itemsProps);
14
+ var savedSelected = (0, react_1.useRef)();
13
15
  var savedOnSelect = (0, react_1.useRef)();
16
+ var _c = tslib_1.__read((0, react_1.useState)({}), 2), state = _c[0], setState = _c[1];
14
17
  (0, react_1.useEffect)(function () {
15
18
  savedItems.current = itemsProps;
16
19
  }, [itemsProps]);
17
20
  (0, react_1.useEffect)(function () {
18
21
  savedOnSelect.current = onSelect;
19
22
  }, [onSelect]);
20
- var _c = tslib_1.__read((0, react_1.useState)({}), 2), state = _c[0], setState = _c[1];
23
+ (0, react_1.useEffect)(function () {
24
+ savedSelected.current = selected;
25
+ }, [selected]);
21
26
  var findInItems = function (value) { var _a; return (_a = savedItems.current) === null || _a === void 0 ? void 0 : _a.find(function (item) { return item === value; }); };
22
- // Актуализирует состояние при каждом изменении текущего значения
23
27
  (0, react_1.useEffect)(function () {
24
- var _a, _b, _c;
25
- if (!active) {
26
- return;
27
- }
28
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: (_a = findInItems(state.focused)) !== null && _a !== void 0 ? _a : null, selected: (_b = findInItems(current)) !== null && _b !== void 0 ? _b : (_c = savedItems.current) === null || _c === void 0 ? void 0 : _c[0] }));
29
- }, [active, current]);
30
- var onMouseLeave = function () {
31
28
  if (!active) {
32
29
  return;
33
30
  }
34
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { highlighted: null }));
35
- };
36
- var onMouseEnter = function (item) {
31
+ setState(function (prevState) {
32
+ var _a, _b, _c;
33
+ return (tslib_1.__assign(tslib_1.__assign({}, prevState), { focused: (_a = findInItems(prevState.focused)) !== null && _a !== void 0 ? _a : null, current: (_b = findInItems(savedSelected.current)) !== null && _b !== void 0 ? _b : (_c = savedItems.current) === null || _c === void 0 ? void 0 : _c[0] }));
34
+ });
35
+ }, [itemsProps, active]);
36
+ // Сброс
37
+ (0, react_1.useEffect)(function () {
37
38
  if (!active) {
38
- return;
39
+ return undefined;
39
40
  }
40
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { highlighted: item }));
41
- };
42
- var onClick = function (event, item) {
41
+ return function () {
42
+ setState({});
43
+ };
44
+ }, [active]);
45
+ var onClick = (0, react_1.useCallback)(function (event, item) {
43
46
  var _a;
44
47
  if (!active) {
45
48
  return;
46
49
  }
47
50
  var focused = item === state.focused ? item : null;
48
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: focused, selected: item }));
51
+ setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: focused, current: item }));
49
52
  (_a = savedOnSelect.current) === null || _a === void 0 ? void 0 : _a.call(savedOnSelect, event, item);
50
- };
51
- var onKeyDown = function (event) {
53
+ }, [state.focused, active]);
54
+ var onKeyDown = (0, react_1.useCallback)(function (event) {
52
55
  var _a, _b, _c, _d, _e, _f, _g;
53
- if (!active) {
56
+ if (!active || !(0, isKeys_1.isKeys)(event, ['Enter', 'ArrowUp', 'ArrowDown'])) {
54
57
  return;
55
58
  }
59
+ var current = (_a = state.focused) !== null && _a !== void 0 ? _a : state.current;
56
60
  if ((0, isKey_1.isKey)(event, 'Enter')) {
61
+ // Не обрабатываем ввод в пустом списке
62
+ if (!((_b = savedItems.current) === null || _b === void 0 ? void 0 : _b.length)) {
63
+ return;
64
+ }
57
65
  event.preventDefault();
58
- var selected_1 = (_a = state.focused) !== null && _a !== void 0 ? _a : state.selected;
59
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { selected: selected_1, focused: selected_1 }));
60
- (_b = savedOnSelect.current) === null || _b === void 0 ? void 0 : _b.call(savedOnSelect, event, selected_1);
61
- }
62
- if (!(0, isKey_1.isKey)(event, 'ArrowUp') && !(0, isKey_1.isKey)(event, 'ArrowDown')) {
63
- return;
66
+ setState(tslib_1.__assign(tslib_1.__assign({}, state), { current: current, focused: current }));
67
+ (_c = savedOnSelect.current) === null || _c === void 0 ? void 0 : _c.call(savedOnSelect, event, current);
64
68
  }
65
- event.preventDefault();
66
- var selected = (_c = state.focused) !== null && _c !== void 0 ? _c : state.selected;
67
- var currentIndex = typeof selected !== 'undefined'
68
- ? (_d = savedItems.current) === null || _d === void 0 ? void 0 : _d.indexOf(selected)
69
- : null;
70
- var isArrowUp = (0, isKey_1.isKey)(event, 'ArrowUp');
71
- var newIndex = isArrowUp
72
- ? (0, getPrevIndex_1.getPrevIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
73
- : (0, getNextIndex_1.getNextIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : -1, ((_f = savedItems.current) === null || _f === void 0 ? void 0 : _f.length) || 0);
74
- var newItem = (_g = savedItems.current) === null || _g === void 0 ? void 0 : _g[newIndex];
75
- setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: newItem }));
76
- };
77
- (0, react_1.useEffect)(function () {
78
- if (!active) {
79
- return undefined;
69
+ if ((0, isKeys_1.isKeys)(event, ['ArrowUp', 'ArrowDown'])) {
70
+ event.preventDefault();
71
+ var currentIndex = typeof current !== 'undefined'
72
+ ? (_d = savedItems.current) === null || _d === void 0 ? void 0 : _d.indexOf(current)
73
+ : null;
74
+ var isArrowUp = (0, isKey_1.isKey)(event, 'ArrowUp');
75
+ var newIndex = isArrowUp
76
+ ? (0, getPrevIndex_1.getPrevIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
77
+ : (0, getNextIndex_1.getNextIndex)(currentIndex !== null && currentIndex !== void 0 ? currentIndex : -1, ((_f = savedItems.current) === null || _f === void 0 ? void 0 : _f.length) || 0);
78
+ var newItem = (_g = savedItems.current) === null || _g === void 0 ? void 0 : _g[newIndex];
79
+ setState(tslib_1.__assign(tslib_1.__assign({}, state), { focused: newItem }));
80
80
  }
81
- return function () {
82
- // Сброс
83
- setState({});
84
- };
85
- }, [active]);
86
- return tslib_1.__assign(tslib_1.__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave });
81
+ }, [state.focused, state.current, active]);
82
+ return tslib_1.__assign(tslib_1.__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown });
87
83
  }
88
84
  exports.useDataListNavigation = useDataListNavigation;
@@ -22,11 +22,11 @@ var PopoverContext_1 = require("./PopoverContext");
22
22
  exports.cnPopover = (0, classname_1.cn)('Popover');
23
23
  exports.Popover = (0, polymorphicComponentWithRef_1.polymorphicComponentWithRef)(function (inProps, ref) {
24
24
  var props = (0, useThemeProps_1.useThemeProps)({ props: inProps, name: 'Popover' });
25
- var _a = props.arrow, arrow = _a === void 0 ? constants_1.POPOVER_DEFAULT_ARROW : _a, _b = props.open, open = _b === void 0 ? constants_1.POPOVER_DEFAULT_OPEN : _b, _c = props.disableInteractive, disableInteractive = _c === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_INTERACTIVE : _c, _d = props.disableEnforceFocus, disableEnforceFocus = _d === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS : _d, _e = props.disableReturnFocus, disableReturnFocus = _e === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_RETURN_FOCUS : _e, _f = props.disableClickOutside, disableClickOutside = _f === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE : _f, _g = props.placement, placement = _g === void 0 ? constants_1.POPOVER_DEFAULT_PLACEMENT : _g, ignoreClickOutsideRefs = props.ignoreClickOutsideRefs, arrowProps = props.arrowProps, anchorRef = props.anchorRef, equalAnchorWidth = props.equalAnchorWidth, offset = props.offset, children = props.children, transitionProps = props.transitionProps, onClose = props.onClose, onEnter = props.onEnter, onEntered = props.onEntered, onExit = props.onExit, onExitedProp = props.onExited, className = props.className, position = props.position, style = props.style, setUpdate = props.setUpdate, _h = props.as, as = _h === void 0 ? constants_1.POPOVER_DEFAULT_TAG : _h, other = tslib_1.__rest(props, ["arrow", "open", "disableInteractive", "disableEnforceFocus", "disableReturnFocus", "disableClickOutside", "placement", "ignoreClickOutsideRefs", "arrowProps", "anchorRef", "equalAnchorWidth", "offset", "children", "transitionProps", "onClose", "onEnter", "onEntered", "onExit", "onExited", "className", "position", "style", "setUpdate", "as"]);
26
- var _j = tslib_1.__read((0, react_1.useState)(false), 2), openState = _j[0], setOpenState = _j[1];
25
+ var _a = props.arrow, arrow = _a === void 0 ? constants_1.POPOVER_DEFAULT_ARROW : _a, _b = props.open, open = _b === void 0 ? constants_1.POPOVER_DEFAULT_OPEN : _b, _c = props.disableInteractive, disableInteractive = _c === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_INTERACTIVE : _c, _d = props.disableEnforceFocus, disableEnforceFocus = _d === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS : _d, _e = props.disableReturnFocus, disableReturnFocus = _e === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_RETURN_FOCUS : _e, _f = props.disableClickOutside, disableClickOutside = _f === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE : _f, _g = props.placement, placement = _g === void 0 ? constants_1.POPOVER_DEFAULT_PLACEMENT : _g, _h = props.strategy, strategy = _h === void 0 ? constants_1.POPOVER_DEFAULT_STRATEGY : _h, _j = props.disablePreventOverflow, disablePreventOverflow = _j === void 0 ? constants_1.POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW : _j, ignoreClickOutsideRefs = props.ignoreClickOutsideRefs, arrowProps = props.arrowProps, anchorRef = props.anchorRef, equalAnchorWidth = props.equalAnchorWidth, offset = props.offset, children = props.children, transitionProps = props.transitionProps, onClose = props.onClose, onEnter = props.onEnter, onEntered = props.onEntered, onExit = props.onExit, onExitedProp = props.onExited, className = props.className, position = props.position, style = props.style, setUpdate = props.setUpdate, _k = props.as, as = _k === void 0 ? constants_1.POPOVER_DEFAULT_TAG : _k, other = tslib_1.__rest(props, ["arrow", "open", "disableInteractive", "disableEnforceFocus", "disableReturnFocus", "disableClickOutside", "placement", "strategy", "disablePreventOverflow", "ignoreClickOutsideRefs", "arrowProps", "anchorRef", "equalAnchorWidth", "offset", "children", "transitionProps", "onClose", "onEnter", "onEntered", "onExit", "onExited", "className", "position", "style", "setUpdate", "as"]);
26
+ var _l = tslib_1.__read((0, react_1.useState)(false), 2), openState = _l[0], setOpenState = _l[1];
27
27
  var focusedElement = (0, react_1.useRef)(null);
28
28
  var popoverRef = (0, react_1.useRef)(null);
29
- var _k = (0, index_1.usePopoverManager)(popoverRef, 1000, openState), refsClickOutside = _k.refsClickOutside, isTop = _k.isTop;
29
+ var _m = (0, index_1.usePopoverManager)(popoverRef, 1000, openState), refsClickOutside = _m.refsClickOutside, isTop = _m.isTop;
30
30
  // Ловушка фокуса
31
31
  var trapRef = (0, useFocusTrap_1.useFocusTrap)({
32
32
  active: !disableEnforceFocus && isTop,
@@ -72,6 +72,7 @@ exports.Popover = (0, polymorphicComponentWithRef_1.polymorphicComponentWithRef)
72
72
  gpuAcceleration: false,
73
73
  },
74
74
  },
75
+ { name: 'preventOverflow', enabled: disablePreventOverflow },
75
76
  // Ширина всплывающего элемента
76
77
  {
77
78
  name: 'sameWidth',
@@ -119,12 +120,12 @@ exports.Popover = (0, polymorphicComponentWithRef_1.polymorphicComponentWithRef)
119
120
  };
120
121
  return undefined;
121
122
  }, [anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current, position]);
122
- var _l = tslib_1.__read((0, react_1.useState)(null), 2), popperElement = _l[0], setPopperElement = _l[1];
123
- var _m = (0, react_popper_1.usePopper)(resolveReferenceElement, popperElement, {
123
+ var _o = tslib_1.__read((0, react_1.useState)(null), 2), popperElement = _o[0], setPopperElement = _o[1];
124
+ var _p = (0, react_popper_1.usePopper)(resolveReferenceElement, popperElement, {
124
125
  placement: placement,
125
- strategy: 'fixed',
126
+ strategy: strategy,
126
127
  modifiers: modifiers,
127
- }), styles = _m.styles, attributes = _m.attributes, update = _m.update;
128
+ }), styles = _p.styles, attributes = _p.attributes, update = _p.update;
128
129
  // Передача метода по перерасчету расположения компонента Popover в родительский компонент
129
130
  (0, react_1.useEffect)(function () {
130
131
  setUpdate === null || setUpdate === void 0 ? void 0 : setUpdate(update);
@@ -6,3 +6,5 @@ export declare const POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = false;
6
6
  export declare const POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = false;
7
7
  export declare const POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = false;
8
8
  export declare const POPOVER_DEFAULT_PLACEMENT = "auto";
9
+ export declare const POPOVER_DEFAULT_STRATEGY = "fixed";
10
+ export declare const POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW = false;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.POPOVER_DEFAULT_PLACEMENT = exports.POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = exports.POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = exports.POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = exports.POPOVER_DEFAULT_DISABLE_INTERACTIVE = exports.POPOVER_DEFAULT_OPEN = exports.POPOVER_DEFAULT_ARROW = exports.POPOVER_DEFAULT_TAG = void 0;
3
+ exports.POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW = exports.POPOVER_DEFAULT_STRATEGY = exports.POPOVER_DEFAULT_PLACEMENT = exports.POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = exports.POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = exports.POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = exports.POPOVER_DEFAULT_DISABLE_INTERACTIVE = exports.POPOVER_DEFAULT_OPEN = exports.POPOVER_DEFAULT_ARROW = exports.POPOVER_DEFAULT_TAG = void 0;
4
4
  var Paper_1 = require("../Paper");
5
5
  exports.POPOVER_DEFAULT_TAG = Paper_1.Paper;
6
6
  exports.POPOVER_DEFAULT_ARROW = false;
@@ -10,3 +10,5 @@ exports.POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = false;
10
10
  exports.POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = false;
11
11
  exports.POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = false;
12
12
  exports.POPOVER_DEFAULT_PLACEMENT = 'auto';
13
+ exports.POPOVER_DEFAULT_STRATEGY = 'fixed';
14
+ exports.POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW = false;
@@ -11,6 +11,8 @@ export type VirtualElement = {
11
11
  };
12
12
  export declare const popoverPlacementVariant: readonly ["top-start", "top-end", "bottom-start", "bottom-end", "right-start", "right-end", "left-start", "left-end", "auto", "auto-start", "auto-end", "top", "bottom", "right", "left"];
13
13
  export type PopoverPlacementVariant = (typeof popoverPlacementVariant)[number];
14
+ export declare const popoverStrategyVariant: readonly ["absolute", "fixed"];
15
+ export type PopoverStrategyVariant = (typeof popoverStrategyVariant)[number];
14
16
  export type PopoverBaseProps = {
15
17
  /** Признак по которому компонент будет представлен */
16
18
  open?: boolean;
@@ -70,6 +72,10 @@ export type PopoverBaseProps = {
70
72
  setUpdate?: (update: PopperJS.Instance['update'] | null) => void;
71
73
  /** Контейнер для монтирования всплывающего окна */
72
74
  container?: PortalProps['container'];
75
+ /** Стратегия позиционирования */
76
+ strategy?: PopoverStrategyVariant;
77
+ /** Если {true} позволяет смещаться по границе якорного элемента компонента */
78
+ disablePreventOverflow?: boolean;
73
79
  };
74
80
  export type PopoverRef = ComponentRef<typeof POPOVER_DEFAULT_TAG>;
75
81
  export type PopoverProps<As extends ElementType = typeof POPOVER_DEFAULT_TAG> = PolymorphicComponentPropsWithRef<PopoverBaseProps, As>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.popoverPlacementVariant = void 0;
3
+ exports.popoverStrategyVariant = exports.popoverPlacementVariant = void 0;
4
4
  exports.popoverPlacementVariant = [
5
5
  'top-start',
6
6
  'top-end',
@@ -18,3 +18,4 @@ exports.popoverPlacementVariant = [
18
18
  'right',
19
19
  'left',
20
20
  ];
21
+ exports.popoverStrategyVariant = ['absolute', 'fixed'];
@@ -115,7 +115,7 @@ exports.Tooltip = (0, polymorphicComponentWithRef_1.polymorphicComponentWithRef)
115
115
  ]);
116
116
  return (react_1.default.createElement(react_1.default.Fragment, null,
117
117
  react_1.default.cloneElement(resolveChildren, composeChildrenProps),
118
- react_1.default.createElement(Popover_1.Popover, tslib_1.__assign({ anchorRef: anchorRef, as: as, background: variant === 'light' ? 'main' : 'main-inverse', radius: size }, other, { ref: ref, offset: offset, placement: placement, open: openState && !disabled, onClose: handleClose, className: (0, exports.cnTooltip)({ size: size, variant: variant }, [className]), disableInteractive: disableInteractive, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, arrow: arrow, arrowProps: {
118
+ react_1.default.createElement(Popover_1.Popover, tslib_1.__assign({ anchorRef: anchorRef, strategy: "absolute", as: as, background: variant === 'light' ? 'main' : 'main-inverse', radius: size }, other, { ref: ref, offset: offset, placement: placement, open: openState && !disabled, onClose: handleClose, className: (0, exports.cnTooltip)({ size: size, variant: variant }, [className]), disableInteractive: disableInteractive, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, arrow: arrow, arrowProps: {
119
119
  size: size,
120
120
  }, disableEnforceFocus: true, disableReturnFocus: true }), label)));
121
121
  });
@@ -1,9 +1,9 @@
1
1
  import type { RefObject } from 'react';
2
2
  export type UseHoverOptions = {
3
3
  /** Функция обратного вызова на событие перехода курсора на целевой элемент */
4
- onEnter?: (e: PointerEvent) => void;
4
+ onEnter?: (e: MouseEvent) => void;
5
5
  /** Функция обратного вызова на событие покидания курсора с целевого элемента */
6
- onLeave?: (e: PointerEvent) => void;
6
+ onLeave?: (e: MouseEvent) => void;
7
7
  /** Признак активности обработчика события, используется для повышения производительности. */
8
8
  active?: boolean;
9
9
  };
@@ -23,13 +23,13 @@ options) {
23
23
  (0, useEventListener_1.useEventListener)({
24
24
  handler: handleEnter,
25
25
  element: elRef,
26
- eventName: 'pointerenter',
26
+ eventName: 'mouseenter',
27
27
  active: active,
28
28
  });
29
29
  (0, useEventListener_1.useEventListener)({
30
30
  handler: handleLeave,
31
31
  element: elRef,
32
- eventName: 'pointerleave',
32
+ eventName: 'mouseleave',
33
33
  active: active,
34
34
  });
35
35
  return value;
@@ -29,6 +29,7 @@ var DataListRender = function (inProps, ref) {
29
29
  state: 'selected',
30
30
  }), 2), selectedState = _g[0], setSelected = _g[1];
31
31
  var nodes = useMemo(function () { return new Map(); }, [children]);
32
+ var items = useMemo(function () { return new Array(); }, [children]);
32
33
  var resolvedChildren = isFragment(children)
33
34
  ? children.props.children
34
35
  : children;
@@ -37,11 +38,14 @@ var DataListRender = function (inProps, ref) {
37
38
  child.type !== DataListOption ||
38
39
  !!child.props.disabled;
39
40
  };
40
- Children.forEach(resolvedChildren, function (child, idx) {
41
- if (!isNotSelectOption(child)) {
42
- nodes.set(child.props.value, idx);
43
- }
44
- });
41
+ useEffect(function () {
42
+ Children.forEach(resolvedChildren, function (child, idx) {
43
+ if (!isNotSelectOption(child)) {
44
+ items.push(child.props.value);
45
+ nodes.set(child.props.value, idx);
46
+ }
47
+ });
48
+ }, [children]);
45
49
  var handleSelect = function (event, value) {
46
50
  var params = {
47
51
  multiple: inProps.multiple,
@@ -50,10 +54,10 @@ var DataListRender = function (inProps, ref) {
50
54
  setSelected: setSelected,
51
55
  };
52
56
  if (isMultipleParams(params)) {
53
- var selected_1 = params.selected, onSelect = params.onSelect, setSelected_1 = params.setSelected;
54
- var res = (selected_1 === null || selected_1 === void 0 ? void 0 : selected_1.includes(value || ''))
55
- ? selected_1.filter(function (item) { return item !== value; })
56
- : __spreadArray(__spreadArray([], __read((selected_1 || [])), false), [value], false);
57
+ var selected = params.selected, onSelect = params.onSelect, setSelected_1 = params.setSelected;
58
+ var res = (selected === null || selected === void 0 ? void 0 : selected.includes(value || ''))
59
+ ? selected.filter(function (item) { return item !== value; })
60
+ : __spreadArray(__spreadArray([], __read((selected || [])), false), [value], false);
57
61
  onSelect === null || onSelect === void 0 ? void 0 : onSelect(event, { name: name, value: res });
58
62
  setSelected_1(res);
59
63
  }
@@ -66,24 +70,24 @@ var DataListRender = function (inProps, ref) {
66
70
  // Навигация по списку
67
71
  var _h = useDataListNavigation({
68
72
  active: opened,
69
- items: __spreadArray([], __read(nodes.keys()), false),
70
- current: lastSelectedValue(selectedState),
73
+ items: items,
74
+ selected: lastSelectedValue(selectedState),
71
75
  onSelect: function (event, item) {
72
76
  handleSelect(event, item || '');
73
77
  },
74
- }), selected = _h.selected, focused = _h.focused, highlighted = _h.highlighted, onKeyDown = _h.onKeyDown, onClick = _h.onClick, onMouseEnter = _h.onMouseEnter, onMouseLeave = _h.onMouseLeave;
78
+ }), current = _h.current, focused = _h.focused, onKeyDown = _h.onKeyDown, onClick = _h.onClick;
75
79
  var _j = __read(useState({ current: null }), 2), selectedElRef = _j[0], setSelectedElRef = _j[1];
76
- // Находит элемент по ключу
77
80
  useEffect(function () {
78
81
  var _a, _b;
79
- var current = focused || selected || '';
80
- var idx = nodes.get(current);
82
+ var selected = focused || current || '';
83
+ // Находит элемент по ключу
84
+ var idx = nodes.get(selected);
81
85
  if (idx !== undefined) {
82
86
  setSelectedElRef({
83
87
  current: (_b = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b[idx],
84
88
  });
85
89
  }
86
- }, [focused, selected]);
90
+ }, [focused, current]);
87
91
  // Прокрутка списка
88
92
  useScrollContainerToElement(dataListRef, selectedElRef, focused ? 'smooth' : 'instant');
89
93
  // Назначает элементу контроля событие управления списком с клавиатуры
@@ -106,37 +110,28 @@ var DataListRender = function (inProps, ref) {
106
110
  },
107
111
  });
108
112
  // Представление раскрывающегося списка
109
- var renderChildren = Children.map(resolvedChildren, function (child) {
110
- if (isNotSelectOption(child)) {
111
- return child;
112
- }
113
- var key = child.props.value;
114
- var elementChild = child;
115
- var props = {
116
- onClick: function (event) {
117
- var _a, _b;
118
- onClick === null || onClick === void 0 ? void 0 : onClick(event, key);
119
- (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
120
- },
121
- onMouseEnter: function (event) {
122
- var _a, _b;
123
- onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(key);
124
- (_b = (_a = child.props).onMouseEnter) === null || _b === void 0 ? void 0 : _b.call(_a, event);
125
- },
126
- onMouseLeave: function (event) {
127
- var _a, _b;
128
- onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave();
129
- (_b = (_a = child.props).onMouseLeave) === null || _b === void 0 ? void 0 : _b.call(_a, event);
130
- },
131
- highlighted: key === highlighted,
132
- focused: key === focused,
133
- selected: Array.isArray(selectedState)
134
- ? selectedState.includes(key)
135
- : selectedState === key,
136
- };
137
- return cloneElement(elementChild, __assign({}, props));
138
- });
139
- return (React.createElement(Popover, __assign({ as: as, open: open, placement: "bottom-start", disableReturnFocus: true, disableEnforceFocus: true, offset: [0, 4], onClose: onClose, anchorRef: anchorRef, className: cnDataList('', [className]), transitionProps: {
113
+ var renderChildren = useMemo(function () {
114
+ return Children.map(resolvedChildren, function (child) {
115
+ if (isNotSelectOption(child)) {
116
+ return child;
117
+ }
118
+ var key = child.props.value;
119
+ var elementChild = child;
120
+ var props = {
121
+ onClick: function (event) {
122
+ var _a, _b;
123
+ onClick === null || onClick === void 0 ? void 0 : onClick(event, key);
124
+ (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
125
+ },
126
+ focused: key === focused,
127
+ selected: Array.isArray(selectedState)
128
+ ? selectedState.includes(key)
129
+ : selectedState === key,
130
+ };
131
+ return cloneElement(elementChild, props);
132
+ });
133
+ }, [resolvedChildren, selectedState, focused, onClick]);
134
+ return (React.createElement(Popover, __assign({ as: as, open: open, placement: "bottom-start", strategy: "absolute", disableReturnFocus: true, disableEnforceFocus: true, offset: [0, 4], onClose: onClose, anchorRef: anchorRef, className: cnDataList('', [className]), transitionProps: {
140
135
  classNames: 'DataList-animation',
141
136
  } }, other, { onEntered: function () {
142
137
  onEntered();
@@ -2,6 +2,7 @@
2
2
  inline-size: var(--data-list-check-icon-size);
3
3
  block-size: var(--data-list-check-icon-size);
4
4
  display: flex;
5
+ flex-shrink: 0;
5
6
  }
6
7
 
7
8
  .DataListCheckIcon_size_s {
@@ -1,20 +1,33 @@
1
1
  .DataListOption {
2
2
  cursor: pointer;
3
+ transition: background-color var(--transition-default);
3
4
  }
4
5
 
5
- .DataListOption_focused {
6
- box-shadow: inset var(--shadow-outline-focused);
6
+ .DataListOption:hover {
7
+ background-color: var(--color-background-main-hover);
7
8
  }
8
9
 
9
- .DataListOption_highlighted {
10
- background-color: var(--color-background-main-hover);
10
+ .DataListOption:active {
11
+ background-color: var(--color-background-main-pressed);
11
12
  }
12
13
 
13
- .DataListOption_disabled {
14
+ .DataListOption_focused {
15
+ box-shadow: inset var(--shadow-outline-focused);
16
+ }
17
+
18
+ .DataListOption_disabled,
19
+ .DataListOption_disabled:hover,
20
+ .DataListOption_disabled:active {
14
21
  cursor: not-allowed;
22
+
23
+ background-color: unset;
15
24
  }
16
25
 
17
26
  .DataListOption_disabled .ListItemText-TextPrimary,
18
- .DataListOption_disabled .ListItemText-TextSecondary {
27
+ .DataListOption_disabled .ListItemText-TextSecondary,
28
+ .DataListOption_disabled:hover .ListItemText-TextPrimary,
29
+ .DataListOption_disabled:hover .ListItemText-TextSecondary,
30
+ .DataListOption_disabled:active .ListItemText-TextPrimary,
31
+ .DataListOption_disabled:active .ListItemText-TextSecondary {
19
32
  color: var(--color-content-tertiary);
20
33
  }
@@ -12,8 +12,6 @@ export type DataListOptionProps = {
12
12
  disabled?: boolean;
13
13
  /** Если {true} отображает опцию сфокусированной (клавиатура) */
14
14
  focused?: boolean;
15
- /** Если {true} отображает опцию наведенной (мышь) */
16
- highlighted?: boolean;
17
15
  /** Если {true} отображает опцию выбранной */
18
16
  selected?: boolean;
19
17
  /** Функция обратного вызова обработчик нажатий на клавиатуре */
@@ -18,7 +18,7 @@ var DataListContent = function (_a) {
18
18
  React.createElement(DataListCheckIcon, { selected: selected, size: iconSize })));
19
19
  };
20
20
  export var DataListOption = forwardRef(function (_a, ref) {
21
- var _b = _a.disabled, disabled = _b === void 0 ? DATA_LIST_OPTION_DEFAULT_DISABLED : _b, value = _a.value, label = _a.label, children = _a.children, className = _a.className, highlighted = _a.highlighted, selected = _a.selected, focused = _a.focused, other = __rest(_a, ["disabled", "value", "label", "children", "className", "highlighted", "selected", "focused"]);
21
+ var _b = _a.disabled, disabled = _b === void 0 ? DATA_LIST_OPTION_DEFAULT_DISABLED : _b, value = _a.value, label = _a.label, children = _a.children, className = _a.className, selected = _a.selected, focused = _a.focused, other = __rest(_a, ["disabled", "value", "label", "children", "className", "selected", "focused"]);
22
22
  var renderChildren = function () {
23
23
  if (isString(children) || isNumber(children)) {
24
24
  return React.createElement(DataListContent, { label: children, selected: selected });
@@ -30,7 +30,7 @@ export var DataListOption = forwardRef(function (_a, ref) {
30
30
  };
31
31
  return (React.createElement(ListItem, __assign({ role: "option", "aria-selected": selected, "aria-disabled": disabled, "data-label": label, "data-value": value, className: cnDataListOption({
32
32
  disabled: disabled,
33
- highlighted: !disabled && highlighted,
33
+ selected: selected,
34
34
  focused: !disabled && focused,
35
35
  }, [className]) }, other, { ref: ref }), renderChildren()));
36
36
  });
@@ -4,20 +4,17 @@ export type UseListNavigationItems = UseListNavigationItem[];
4
4
  export type UseListNavigationProps = {
5
5
  active?: boolean;
6
6
  items?: UseListNavigationItems;
7
- current?: UseListNavigationItem;
7
+ selected?: UseListNavigationItem;
8
8
  onSelect?: (event: KeyboardEvent | MouseEvent<HTMLElement>, item?: UseListNavigationItem) => void;
9
9
  };
10
10
  export type UseListNavigationState = {
11
11
  focused?: UseListNavigationItem;
12
- selected?: UseListNavigationItem;
13
- highlighted?: UseListNavigationItem;
12
+ current?: UseListNavigationItem;
14
13
  };
15
14
  export type UseListNavigationEvents = {
16
- onMouseLeave?: () => void;
17
15
  onKeyDown?: (event: KeyboardEvent) => void;
18
16
  onClick?: (event: MouseEvent<HTMLElement>, item: UseListNavigationItem) => void;
19
- onMouseEnter?: (item: UseListNavigationItem) => void;
20
17
  };
21
18
  export type UseListNavigationReturn = UseListNavigationState & UseListNavigationEvents;
22
19
  /** Навигация по элементам списка без перехвата фокуса с элемента контроля */
23
- export declare function useDataListNavigation({ current, onSelect, active, items: itemsProps, }: UseListNavigationProps): UseListNavigationReturn;
20
+ export declare function useDataListNavigation({ selected, onSelect, active, items: itemsProps, }: UseListNavigationProps): UseListNavigationReturn;
@@ -1,84 +1,80 @@
1
1
  import { __assign, __read } from "tslib";
2
- import { useEffect, useState, useRef } from 'react';
2
+ import { useEffect, useState, useRef, useCallback } from 'react';
3
3
  import { getNextIndex } from '../../../utils/getNextIndex';
4
4
  import { getPrevIndex } from '../../../utils/getPrevIndex';
5
5
  import { isKey } from '../../../utils/isKey';
6
+ import { isKeys } from '../../../utils/isKeys';
6
7
  /** Навигация по элементам списка без перехвата фокуса с элемента контроля */
7
8
  export function useDataListNavigation(_a) {
8
- var current = _a.current, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
9
+ var selected = _a.selected, onSelect = _a.onSelect, _b = _a.active, active = _b === void 0 ? false : _b, itemsProps = _a.items;
9
10
  var savedItems = useRef(itemsProps);
11
+ var savedSelected = useRef();
10
12
  var savedOnSelect = useRef();
13
+ var _c = __read(useState({}), 2), state = _c[0], setState = _c[1];
11
14
  useEffect(function () {
12
15
  savedItems.current = itemsProps;
13
16
  }, [itemsProps]);
14
17
  useEffect(function () {
15
18
  savedOnSelect.current = onSelect;
16
19
  }, [onSelect]);
17
- var _c = __read(useState({}), 2), state = _c[0], setState = _c[1];
20
+ useEffect(function () {
21
+ savedSelected.current = selected;
22
+ }, [selected]);
18
23
  var findInItems = function (value) { var _a; return (_a = savedItems.current) === null || _a === void 0 ? void 0 : _a.find(function (item) { return item === value; }); };
19
- // Актуализирует состояние при каждом изменении текущего значения
20
24
  useEffect(function () {
21
- var _a, _b, _c;
22
- if (!active) {
23
- return;
24
- }
25
- setState(__assign(__assign({}, state), { focused: (_a = findInItems(state.focused)) !== null && _a !== void 0 ? _a : null, selected: (_b = findInItems(current)) !== null && _b !== void 0 ? _b : (_c = savedItems.current) === null || _c === void 0 ? void 0 : _c[0] }));
26
- }, [active, current]);
27
- var onMouseLeave = function () {
28
25
  if (!active) {
29
26
  return;
30
27
  }
31
- setState(__assign(__assign({}, state), { highlighted: null }));
32
- };
33
- var onMouseEnter = function (item) {
28
+ setState(function (prevState) {
29
+ var _a, _b, _c;
30
+ return (__assign(__assign({}, prevState), { focused: (_a = findInItems(prevState.focused)) !== null && _a !== void 0 ? _a : null, current: (_b = findInItems(savedSelected.current)) !== null && _b !== void 0 ? _b : (_c = savedItems.current) === null || _c === void 0 ? void 0 : _c[0] }));
31
+ });
32
+ }, [itemsProps, active]);
33
+ // Сброс
34
+ useEffect(function () {
34
35
  if (!active) {
35
- return;
36
+ return undefined;
36
37
  }
37
- setState(__assign(__assign({}, state), { highlighted: item }));
38
- };
39
- var onClick = function (event, item) {
38
+ return function () {
39
+ setState({});
40
+ };
41
+ }, [active]);
42
+ var onClick = useCallback(function (event, item) {
40
43
  var _a;
41
44
  if (!active) {
42
45
  return;
43
46
  }
44
47
  var focused = item === state.focused ? item : null;
45
- setState(__assign(__assign({}, state), { focused: focused, selected: item }));
48
+ setState(__assign(__assign({}, state), { focused: focused, current: item }));
46
49
  (_a = savedOnSelect.current) === null || _a === void 0 ? void 0 : _a.call(savedOnSelect, event, item);
47
- };
48
- var onKeyDown = function (event) {
50
+ }, [state.focused, active]);
51
+ var onKeyDown = useCallback(function (event) {
49
52
  var _a, _b, _c, _d, _e, _f, _g;
50
- if (!active) {
53
+ if (!active || !isKeys(event, ['Enter', 'ArrowUp', 'ArrowDown'])) {
51
54
  return;
52
55
  }
56
+ var current = (_a = state.focused) !== null && _a !== void 0 ? _a : state.current;
53
57
  if (isKey(event, 'Enter')) {
58
+ // Не обрабатываем ввод в пустом списке
59
+ if (!((_b = savedItems.current) === null || _b === void 0 ? void 0 : _b.length)) {
60
+ return;
61
+ }
54
62
  event.preventDefault();
55
- var selected_1 = (_a = state.focused) !== null && _a !== void 0 ? _a : state.selected;
56
- setState(__assign(__assign({}, state), { selected: selected_1, focused: selected_1 }));
57
- (_b = savedOnSelect.current) === null || _b === void 0 ? void 0 : _b.call(savedOnSelect, event, selected_1);
58
- }
59
- if (!isKey(event, 'ArrowUp') && !isKey(event, 'ArrowDown')) {
60
- return;
63
+ setState(__assign(__assign({}, state), { current: current, focused: current }));
64
+ (_c = savedOnSelect.current) === null || _c === void 0 ? void 0 : _c.call(savedOnSelect, event, current);
61
65
  }
62
- event.preventDefault();
63
- var selected = (_c = state.focused) !== null && _c !== void 0 ? _c : state.selected;
64
- var currentIndex = typeof selected !== 'undefined'
65
- ? (_d = savedItems.current) === null || _d === void 0 ? void 0 : _d.indexOf(selected)
66
- : null;
67
- var isArrowUp = isKey(event, 'ArrowUp');
68
- var newIndex = isArrowUp
69
- ? getPrevIndex(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
70
- : getNextIndex(currentIndex !== null && currentIndex !== void 0 ? currentIndex : -1, ((_f = savedItems.current) === null || _f === void 0 ? void 0 : _f.length) || 0);
71
- var newItem = (_g = savedItems.current) === null || _g === void 0 ? void 0 : _g[newIndex];
72
- setState(__assign(__assign({}, state), { focused: newItem }));
73
- };
74
- useEffect(function () {
75
- if (!active) {
76
- return undefined;
66
+ if (isKeys(event, ['ArrowUp', 'ArrowDown'])) {
67
+ event.preventDefault();
68
+ var currentIndex = typeof current !== 'undefined'
69
+ ? (_d = savedItems.current) === null || _d === void 0 ? void 0 : _d.indexOf(current)
70
+ : null;
71
+ var isArrowUp = isKey(event, 'ArrowUp');
72
+ var newIndex = isArrowUp
73
+ ? getPrevIndex(currentIndex !== null && currentIndex !== void 0 ? currentIndex : 0, ((_e = savedItems.current) === null || _e === void 0 ? void 0 : _e.length) || 0)
74
+ : getNextIndex(currentIndex !== null && currentIndex !== void 0 ? currentIndex : -1, ((_f = savedItems.current) === null || _f === void 0 ? void 0 : _f.length) || 0);
75
+ var newItem = (_g = savedItems.current) === null || _g === void 0 ? void 0 : _g[newIndex];
76
+ setState(__assign(__assign({}, state), { focused: newItem }));
77
77
  }
78
- return function () {
79
- // Сброс
80
- setState({});
81
- };
82
- }, [active]);
83
- return __assign(__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave });
78
+ }, [state.focused, state.current, active]);
79
+ return __assign(__assign({}, state), { onClick: onClick, onKeyDown: onKeyDown });
84
80
  }
@@ -13,17 +13,17 @@ import { isKey } from '../../utils/isKey';
13
13
  import { polymorphicComponentWithRef } from '../../utils/polymorphicComponentWithRef';
14
14
  import { Portal } from '../Portal';
15
15
  import { PopoverArrow } from './components';
16
- import { POPOVER_DEFAULT_TAG, POPOVER_DEFAULT_ARROW, POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE, POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS, POPOVER_DEFAULT_DISABLE_INTERACTIVE, POPOVER_DEFAULT_DISABLE_RETURN_FOCUS, POPOVER_DEFAULT_OPEN, POPOVER_DEFAULT_PLACEMENT, } from './constants';
16
+ import { POPOVER_DEFAULT_TAG, POPOVER_DEFAULT_ARROW, POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE, POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS, POPOVER_DEFAULT_DISABLE_INTERACTIVE, POPOVER_DEFAULT_DISABLE_RETURN_FOCUS, POPOVER_DEFAULT_OPEN, POPOVER_DEFAULT_PLACEMENT, POPOVER_DEFAULT_STRATEGY, POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW, } from './constants';
17
17
  import { usePopoverManager } from './index';
18
18
  import { PopoverContext } from './PopoverContext';
19
19
  export var cnPopover = cn('Popover');
20
20
  export var Popover = polymorphicComponentWithRef(function (inProps, ref) {
21
21
  var props = useThemeProps({ props: inProps, name: 'Popover' });
22
- var _a = props.arrow, arrow = _a === void 0 ? POPOVER_DEFAULT_ARROW : _a, _b = props.open, open = _b === void 0 ? POPOVER_DEFAULT_OPEN : _b, _c = props.disableInteractive, disableInteractive = _c === void 0 ? POPOVER_DEFAULT_DISABLE_INTERACTIVE : _c, _d = props.disableEnforceFocus, disableEnforceFocus = _d === void 0 ? POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS : _d, _e = props.disableReturnFocus, disableReturnFocus = _e === void 0 ? POPOVER_DEFAULT_DISABLE_RETURN_FOCUS : _e, _f = props.disableClickOutside, disableClickOutside = _f === void 0 ? POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE : _f, _g = props.placement, placement = _g === void 0 ? POPOVER_DEFAULT_PLACEMENT : _g, ignoreClickOutsideRefs = props.ignoreClickOutsideRefs, arrowProps = props.arrowProps, anchorRef = props.anchorRef, equalAnchorWidth = props.equalAnchorWidth, offset = props.offset, children = props.children, transitionProps = props.transitionProps, onClose = props.onClose, onEnter = props.onEnter, onEntered = props.onEntered, onExit = props.onExit, onExitedProp = props.onExited, className = props.className, position = props.position, style = props.style, setUpdate = props.setUpdate, _h = props.as, as = _h === void 0 ? POPOVER_DEFAULT_TAG : _h, other = __rest(props, ["arrow", "open", "disableInteractive", "disableEnforceFocus", "disableReturnFocus", "disableClickOutside", "placement", "ignoreClickOutsideRefs", "arrowProps", "anchorRef", "equalAnchorWidth", "offset", "children", "transitionProps", "onClose", "onEnter", "onEntered", "onExit", "onExited", "className", "position", "style", "setUpdate", "as"]);
23
- var _j = __read(useState(false), 2), openState = _j[0], setOpenState = _j[1];
22
+ var _a = props.arrow, arrow = _a === void 0 ? POPOVER_DEFAULT_ARROW : _a, _b = props.open, open = _b === void 0 ? POPOVER_DEFAULT_OPEN : _b, _c = props.disableInteractive, disableInteractive = _c === void 0 ? POPOVER_DEFAULT_DISABLE_INTERACTIVE : _c, _d = props.disableEnforceFocus, disableEnforceFocus = _d === void 0 ? POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS : _d, _e = props.disableReturnFocus, disableReturnFocus = _e === void 0 ? POPOVER_DEFAULT_DISABLE_RETURN_FOCUS : _e, _f = props.disableClickOutside, disableClickOutside = _f === void 0 ? POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE : _f, _g = props.placement, placement = _g === void 0 ? POPOVER_DEFAULT_PLACEMENT : _g, _h = props.strategy, strategy = _h === void 0 ? POPOVER_DEFAULT_STRATEGY : _h, _j = props.disablePreventOverflow, disablePreventOverflow = _j === void 0 ? POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW : _j, ignoreClickOutsideRefs = props.ignoreClickOutsideRefs, arrowProps = props.arrowProps, anchorRef = props.anchorRef, equalAnchorWidth = props.equalAnchorWidth, offset = props.offset, children = props.children, transitionProps = props.transitionProps, onClose = props.onClose, onEnter = props.onEnter, onEntered = props.onEntered, onExit = props.onExit, onExitedProp = props.onExited, className = props.className, position = props.position, style = props.style, setUpdate = props.setUpdate, _k = props.as, as = _k === void 0 ? POPOVER_DEFAULT_TAG : _k, other = __rest(props, ["arrow", "open", "disableInteractive", "disableEnforceFocus", "disableReturnFocus", "disableClickOutside", "placement", "strategy", "disablePreventOverflow", "ignoreClickOutsideRefs", "arrowProps", "anchorRef", "equalAnchorWidth", "offset", "children", "transitionProps", "onClose", "onEnter", "onEntered", "onExit", "onExited", "className", "position", "style", "setUpdate", "as"]);
23
+ var _l = __read(useState(false), 2), openState = _l[0], setOpenState = _l[1];
24
24
  var focusedElement = useRef(null);
25
25
  var popoverRef = useRef(null);
26
- var _k = usePopoverManager(popoverRef, 1000, openState), refsClickOutside = _k.refsClickOutside, isTop = _k.isTop;
26
+ var _m = usePopoverManager(popoverRef, 1000, openState), refsClickOutside = _m.refsClickOutside, isTop = _m.isTop;
27
27
  // Ловушка фокуса
28
28
  var trapRef = useFocusTrap({
29
29
  active: !disableEnforceFocus && isTop,
@@ -69,6 +69,7 @@ export var Popover = polymorphicComponentWithRef(function (inProps, ref) {
69
69
  gpuAcceleration: false,
70
70
  },
71
71
  },
72
+ { name: 'preventOverflow', enabled: disablePreventOverflow },
72
73
  // Ширина всплывающего элемента
73
74
  {
74
75
  name: 'sameWidth',
@@ -116,12 +117,12 @@ export var Popover = polymorphicComponentWithRef(function (inProps, ref) {
116
117
  };
117
118
  return undefined;
118
119
  }, [anchorRef === null || anchorRef === void 0 ? void 0 : anchorRef.current, position]);
119
- var _l = __read(useState(null), 2), popperElement = _l[0], setPopperElement = _l[1];
120
- var _m = usePopper(resolveReferenceElement, popperElement, {
120
+ var _o = __read(useState(null), 2), popperElement = _o[0], setPopperElement = _o[1];
121
+ var _p = usePopper(resolveReferenceElement, popperElement, {
121
122
  placement: placement,
122
- strategy: 'fixed',
123
+ strategy: strategy,
123
124
  modifiers: modifiers,
124
- }), styles = _m.styles, attributes = _m.attributes, update = _m.update;
125
+ }), styles = _p.styles, attributes = _p.attributes, update = _p.update;
125
126
  // Передача метода по перерасчету расположения компонента Popover в родительский компонент
126
127
  useEffect(function () {
127
128
  setUpdate === null || setUpdate === void 0 ? void 0 : setUpdate(update);
@@ -6,3 +6,5 @@ export declare const POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = false;
6
6
  export declare const POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = false;
7
7
  export declare const POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = false;
8
8
  export declare const POPOVER_DEFAULT_PLACEMENT = "auto";
9
+ export declare const POPOVER_DEFAULT_STRATEGY = "fixed";
10
+ export declare const POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW = false;
@@ -7,3 +7,5 @@ export var POPOVER_DEFAULT_DISABLE_ENFORCE_FOCUS = false;
7
7
  export var POPOVER_DEFAULT_DISABLE_RETURN_FOCUS = false;
8
8
  export var POPOVER_DEFAULT_DISABLE_CLICK_OUTSIDE = false;
9
9
  export var POPOVER_DEFAULT_PLACEMENT = 'auto';
10
+ export var POPOVER_DEFAULT_STRATEGY = 'fixed';
11
+ export var POPOVER_DEFAULT_DISABLE_PREVENT_OVERFLOW = false;
@@ -11,6 +11,8 @@ export type VirtualElement = {
11
11
  };
12
12
  export declare const popoverPlacementVariant: readonly ["top-start", "top-end", "bottom-start", "bottom-end", "right-start", "right-end", "left-start", "left-end", "auto", "auto-start", "auto-end", "top", "bottom", "right", "left"];
13
13
  export type PopoverPlacementVariant = (typeof popoverPlacementVariant)[number];
14
+ export declare const popoverStrategyVariant: readonly ["absolute", "fixed"];
15
+ export type PopoverStrategyVariant = (typeof popoverStrategyVariant)[number];
14
16
  export type PopoverBaseProps = {
15
17
  /** Признак по которому компонент будет представлен */
16
18
  open?: boolean;
@@ -70,6 +72,10 @@ export type PopoverBaseProps = {
70
72
  setUpdate?: (update: PopperJS.Instance['update'] | null) => void;
71
73
  /** Контейнер для монтирования всплывающего окна */
72
74
  container?: PortalProps['container'];
75
+ /** Стратегия позиционирования */
76
+ strategy?: PopoverStrategyVariant;
77
+ /** Если {true} позволяет смещаться по границе якорного элемента компонента */
78
+ disablePreventOverflow?: boolean;
73
79
  };
74
80
  export type PopoverRef = ComponentRef<typeof POPOVER_DEFAULT_TAG>;
75
81
  export type PopoverProps<As extends ElementType = typeof POPOVER_DEFAULT_TAG> = PolymorphicComponentPropsWithRef<PopoverBaseProps, As>;
@@ -15,3 +15,4 @@ export var popoverPlacementVariant = [
15
15
  'right',
16
16
  'left',
17
17
  ];
18
+ export var popoverStrategyVariant = ['absolute', 'fixed'];
@@ -112,7 +112,7 @@ export var Tooltip = polymorphicComponentWithRef(function (inProps, ref) {
112
112
  ]);
113
113
  return (React.createElement(React.Fragment, null,
114
114
  React.cloneElement(resolveChildren, composeChildrenProps),
115
- React.createElement(Popover, __assign({ anchorRef: anchorRef, as: as, background: variant === 'light' ? 'main' : 'main-inverse', radius: size }, other, { ref: ref, offset: offset, placement: placement, open: openState && !disabled, onClose: handleClose, className: cnTooltip({ size: size, variant: variant }, [className]), disableInteractive: disableInteractive, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, arrow: arrow, arrowProps: {
115
+ React.createElement(Popover, __assign({ anchorRef: anchorRef, strategy: "absolute", as: as, background: variant === 'light' ? 'main' : 'main-inverse', radius: size }, other, { ref: ref, offset: offset, placement: placement, open: openState && !disabled, onClose: handleClose, className: cnTooltip({ size: size, variant: variant }, [className]), disableInteractive: disableInteractive, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, arrow: arrow, arrowProps: {
116
116
  size: size,
117
117
  }, disableEnforceFocus: true, disableReturnFocus: true }), label)));
118
118
  });
@@ -1,9 +1,9 @@
1
1
  import type { RefObject } from 'react';
2
2
  export type UseHoverOptions = {
3
3
  /** Функция обратного вызова на событие перехода курсора на целевой элемент */
4
- onEnter?: (e: PointerEvent) => void;
4
+ onEnter?: (e: MouseEvent) => void;
5
5
  /** Функция обратного вызова на событие покидания курсора с целевого элемента */
6
- onLeave?: (e: PointerEvent) => void;
6
+ onLeave?: (e: MouseEvent) => void;
7
7
  /** Признак активности обработчика события, используется для повышения производительности. */
8
8
  active?: boolean;
9
9
  };
@@ -20,13 +20,13 @@ options) {
20
20
  useEventListener({
21
21
  handler: handleEnter,
22
22
  element: elRef,
23
- eventName: 'pointerenter',
23
+ eventName: 'mouseenter',
24
24
  active: active,
25
25
  });
26
26
  useEventListener({
27
27
  handler: handleLeave,
28
28
  element: elRef,
29
- eventName: 'pointerleave',
29
+ eventName: 'mouseleave',
30
30
  active: active,
31
31
  });
32
32
  return value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozen-ui/kit",
3
- "version": "0.32.1",
3
+ "version": "0.33.0",
4
4
  "description": "React component library",
5
5
  "files": [
6
6
  "*"