@ozen-ui/kit 0.32.1 → 0.32.2

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.
@@ -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,36 +113,27 @@ 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
- });
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]);
142
137
  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: {
143
138
  classNames: 'DataList-animation',
144
139
  } }, other, { onEntered: function () {
@@ -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,13 +1,18 @@
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);
12
+ }
13
+
14
+ .DataListOption_focused {
15
+ box-shadow: inset var(--shadow-outline-focused);
11
16
  }
12
17
 
13
18
  .DataListOption_disabled {
@@ -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;
@@ -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,36 +110,27 @@ 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
- });
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]);
139
134
  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: {
140
135
  classNames: 'DataList-animation',
141
136
  } }, other, { onEntered: function () {
@@ -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,13 +1,18 @@
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);
12
+ }
13
+
14
+ .DataListOption_focused {
15
+ box-shadow: inset var(--shadow-outline-focused);
11
16
  }
12
17
 
13
18
  .DataListOption_disabled {
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ozen-ui/kit",
3
- "version": "0.32.1",
3
+ "version": "0.32.2",
4
4
  "description": "React component library",
5
5
  "files": [
6
6
  "*"