@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.
- package/__inner__/cjs/components/DataList/DataList.js +41 -46
- package/__inner__/cjs/components/DataList/components/DataListCheckIcon/DataListCheckIcon.css +1 -0
- package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.css +9 -4
- package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.d.ts +0 -2
- package/__inner__/cjs/components/DataList/components/DataListOption/DataListOption.js +2 -2
- package/__inner__/cjs/components/DataList/helpers/useDataListNavigation.d.ts +3 -6
- package/__inner__/cjs/components/DataList/helpers/useDataListNavigation.js +44 -48
- package/__inner__/esm/components/DataList/DataList.js +41 -46
- package/__inner__/esm/components/DataList/components/DataListCheckIcon/DataListCheckIcon.css +1 -0
- package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.css +9 -4
- package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.d.ts +0 -2
- package/__inner__/esm/components/DataList/components/DataListOption/DataListOption.js +2 -2
- package/__inner__/esm/components/DataList/helpers/useDataListNavigation.d.ts +3 -6
- package/__inner__/esm/components/DataList/helpers/useDataListNavigation.js +45 -49
- 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.
|
|
44
|
-
|
|
45
|
-
|
|
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
|
|
57
|
-
var res = (
|
|
58
|
-
?
|
|
59
|
-
: tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((
|
|
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:
|
|
73
|
-
|
|
76
|
+
items: items,
|
|
77
|
+
selected: (0, helpers_1.lastSelectedValue)(selectedState),
|
|
74
78
|
onSelect: function (event, item) {
|
|
75
79
|
handleSelect(event, item || '');
|
|
76
80
|
},
|
|
77
|
-
}),
|
|
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
|
|
83
|
-
|
|
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,
|
|
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.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
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 () {
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
.DataListOption {
|
|
2
2
|
cursor: pointer;
|
|
3
|
+
transition: background-color var(--transition-default);
|
|
3
4
|
}
|
|
4
5
|
|
|
5
|
-
.
|
|
6
|
-
|
|
6
|
+
.DataListOption:hover {
|
|
7
|
+
background-color: var(--color-background-main-hover);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
.
|
|
10
|
-
background-color: var(--color-background-main-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
|
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
|
-
|
|
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(
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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,
|
|
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
|
-
|
|
59
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
|
54
|
-
var res = (
|
|
55
|
-
?
|
|
56
|
-
: __spreadArray(__spreadArray([], __read((
|
|
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:
|
|
70
|
-
|
|
73
|
+
items: items,
|
|
74
|
+
selected: lastSelectedValue(selectedState),
|
|
71
75
|
onSelect: function (event, item) {
|
|
72
76
|
handleSelect(event, item || '');
|
|
73
77
|
},
|
|
74
|
-
}),
|
|
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
|
|
80
|
-
|
|
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,
|
|
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 =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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 () {
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
.DataListOption {
|
|
2
2
|
cursor: pointer;
|
|
3
|
+
transition: background-color var(--transition-default);
|
|
3
4
|
}
|
|
4
5
|
|
|
5
|
-
.
|
|
6
|
-
|
|
6
|
+
.DataListOption:hover {
|
|
7
|
+
background-color: var(--color-background-main-hover);
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
.
|
|
10
|
-
background-color: var(--color-background-main-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
|
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
|
-
|
|
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(
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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,
|
|
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
|
-
|
|
56
|
-
|
|
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
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
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
|
}
|