@rc-component/cascader 1.0.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.
- package/LICENSE.md +9 -0
- package/README.md +300 -0
- package/assets/index.less +3 -0
- package/assets/list.less +106 -0
- package/assets/panel.less +7 -0
- package/assets/select.less +3 -0
- package/es/Cascader.d.ts +88 -0
- package/es/Cascader.js +230 -0
- package/es/OptionList/CacheContent.d.ts +7 -0
- package/es/OptionList/CacheContent.js +8 -0
- package/es/OptionList/Checkbox.d.ts +10 -0
- package/es/OptionList/Checkbox.js +24 -0
- package/es/OptionList/Column.d.ts +21 -0
- package/es/OptionList/Column.js +175 -0
- package/es/OptionList/List.d.ts +6 -0
- package/es/OptionList/List.js +216 -0
- package/es/OptionList/index.d.ts +4 -0
- package/es/OptionList/index.js +13 -0
- package/es/OptionList/useActive.d.ts +6 -0
- package/es/OptionList/useActive.js +26 -0
- package/es/OptionList/useKeyboard.d.ts +10 -0
- package/es/OptionList/useKeyboard.js +165 -0
- package/es/Panel.d.ts +5 -0
- package/es/Panel.js +116 -0
- package/es/context.d.ts +21 -0
- package/es/context.js +3 -0
- package/es/hooks/useDisplayValues.d.ts +10 -0
- package/es/hooks/useDisplayValues.js +44 -0
- package/es/hooks/useEntities.d.ts +10 -0
- package/es/hooks/useEntities.js +35 -0
- package/es/hooks/useMissingValues.d.ts +3 -0
- package/es/hooks/useMissingValues.js +17 -0
- package/es/hooks/useOptions.d.ts +9 -0
- package/es/hooks/useOptions.js +20 -0
- package/es/hooks/useSearchConfig.d.ts +2 -0
- package/es/hooks/useSearchConfig.js +27 -0
- package/es/hooks/useSearchOptions.d.ts +4 -0
- package/es/hooks/useSearchOptions.js +63 -0
- package/es/hooks/useSelect.d.ts +4 -0
- package/es/hooks/useSelect.js +49 -0
- package/es/hooks/useValues.d.ts +9 -0
- package/es/hooks/useValues.js +21 -0
- package/es/index.d.ts +5 -0
- package/es/index.js +4 -0
- package/es/utils/commonUtil.d.ts +18 -0
- package/es/utils/commonUtil.js +69 -0
- package/es/utils/treeUtil.d.ts +9 -0
- package/es/utils/treeUtil.js +35 -0
- package/es/utils/warningPropsUtil.d.ts +4 -0
- package/es/utils/warningPropsUtil.js +29 -0
- package/lib/Cascader.d.ts +88 -0
- package/lib/Cascader.js +239 -0
- package/lib/OptionList/CacheContent.d.ts +7 -0
- package/lib/OptionList/CacheContent.js +16 -0
- package/lib/OptionList/Checkbox.d.ts +10 -0
- package/lib/OptionList/Checkbox.js +33 -0
- package/lib/OptionList/Column.d.ts +21 -0
- package/lib/OptionList/Column.js +185 -0
- package/lib/OptionList/List.d.ts +6 -0
- package/lib/OptionList/List.js +224 -0
- package/lib/OptionList/index.d.ts +4 -0
- package/lib/OptionList/index.js +22 -0
- package/lib/OptionList/useActive.d.ts +6 -0
- package/lib/OptionList/useActive.js +34 -0
- package/lib/OptionList/useKeyboard.d.ts +10 -0
- package/lib/OptionList/useKeyboard.js +175 -0
- package/lib/Panel.d.ts +5 -0
- package/lib/Panel.js +125 -0
- package/lib/context.d.ts +21 -0
- package/lib/context.js +11 -0
- package/lib/hooks/useDisplayValues.d.ts +10 -0
- package/lib/hooks/useDisplayValues.js +53 -0
- package/lib/hooks/useEntities.d.ts +10 -0
- package/lib/hooks/useEntities.js +44 -0
- package/lib/hooks/useMissingValues.d.ts +3 -0
- package/lib/hooks/useMissingValues.js +25 -0
- package/lib/hooks/useOptions.d.ts +9 -0
- package/lib/hooks/useOptions.js +29 -0
- package/lib/hooks/useSearchConfig.d.ts +2 -0
- package/lib/hooks/useSearchConfig.js +36 -0
- package/lib/hooks/useSearchOptions.d.ts +4 -0
- package/lib/hooks/useSearchOptions.js +71 -0
- package/lib/hooks/useSelect.d.ts +4 -0
- package/lib/hooks/useSelect.js +55 -0
- package/lib/hooks/useValues.d.ts +9 -0
- package/lib/hooks/useValues.js +29 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +16 -0
- package/lib/utils/commonUtil.d.ts +18 -0
- package/lib/utils/commonUtil.js +83 -0
- package/lib/utils/treeUtil.d.ts +9 -0
- package/lib/utils/treeUtil.js +42 -0
- package/lib/utils/warningPropsUtil.d.ts +4 -0
- package/lib/utils/warningPropsUtil.js +37 -0
- package/package.json +88 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _context = _interopRequireDefault(require("../context"));
|
|
10
|
+
var _commonUtil = require("../utils/commonUtil");
|
|
11
|
+
var _treeUtil = require("../utils/treeUtil");
|
|
12
|
+
var _CacheContent = _interopRequireDefault(require("./CacheContent"));
|
|
13
|
+
var _Column = _interopRequireWildcard(require("./Column"));
|
|
14
|
+
var _useActive = _interopRequireDefault(require("./useActive"));
|
|
15
|
+
var _useKeyboard = _interopRequireDefault(require("./useKeyboard"));
|
|
16
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
17
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
18
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* eslint-disable default-case */
|
|
20
|
+
const RawOptionList = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
21
|
+
const {
|
|
22
|
+
prefixCls,
|
|
23
|
+
multiple,
|
|
24
|
+
searchValue,
|
|
25
|
+
toggleOpen,
|
|
26
|
+
notFoundContent,
|
|
27
|
+
direction,
|
|
28
|
+
open,
|
|
29
|
+
disabled
|
|
30
|
+
} = props;
|
|
31
|
+
const containerRef = React.useRef(null);
|
|
32
|
+
const rtl = direction === 'rtl';
|
|
33
|
+
const {
|
|
34
|
+
options,
|
|
35
|
+
values,
|
|
36
|
+
halfValues,
|
|
37
|
+
fieldNames,
|
|
38
|
+
changeOnSelect,
|
|
39
|
+
onSelect,
|
|
40
|
+
searchOptions,
|
|
41
|
+
dropdownPrefixCls,
|
|
42
|
+
loadData,
|
|
43
|
+
expandTrigger
|
|
44
|
+
} = React.useContext(_context.default);
|
|
45
|
+
const mergedPrefixCls = dropdownPrefixCls || prefixCls;
|
|
46
|
+
|
|
47
|
+
// ========================= loadData =========================
|
|
48
|
+
const [loadingKeys, setLoadingKeys] = React.useState([]);
|
|
49
|
+
const internalLoadData = valueCells => {
|
|
50
|
+
// Do not load when search
|
|
51
|
+
if (!loadData || searchValue) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const optionList = (0, _treeUtil.toPathOptions)(valueCells, options, fieldNames);
|
|
55
|
+
const rawOptions = optionList.map(({
|
|
56
|
+
option
|
|
57
|
+
}) => option);
|
|
58
|
+
const lastOption = rawOptions[rawOptions.length - 1];
|
|
59
|
+
if (lastOption && !(0, _commonUtil.isLeaf)(lastOption, fieldNames)) {
|
|
60
|
+
const pathKey = (0, _commonUtil.toPathKey)(valueCells);
|
|
61
|
+
setLoadingKeys(keys => [...keys, pathKey]);
|
|
62
|
+
loadData(rawOptions);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// zombieJ: This is bad. We should make this same as `rc-tree` to use Promise instead.
|
|
67
|
+
React.useEffect(() => {
|
|
68
|
+
if (loadingKeys.length) {
|
|
69
|
+
loadingKeys.forEach(loadingKey => {
|
|
70
|
+
const valueStrCells = (0, _commonUtil.toPathValueStr)(loadingKey);
|
|
71
|
+
const optionList = (0, _treeUtil.toPathOptions)(valueStrCells, options, fieldNames, true).map(({
|
|
72
|
+
option
|
|
73
|
+
}) => option);
|
|
74
|
+
const lastOption = optionList[optionList.length - 1];
|
|
75
|
+
if (!lastOption || lastOption[fieldNames.children] || (0, _commonUtil.isLeaf)(lastOption, fieldNames)) {
|
|
76
|
+
setLoadingKeys(keys => keys.filter(key => key !== loadingKey));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}, [options, loadingKeys, fieldNames]);
|
|
81
|
+
|
|
82
|
+
// ========================== Values ==========================
|
|
83
|
+
const checkedSet = React.useMemo(() => new Set((0, _commonUtil.toPathKeys)(values)), [values]);
|
|
84
|
+
const halfCheckedSet = React.useMemo(() => new Set((0, _commonUtil.toPathKeys)(halfValues)), [halfValues]);
|
|
85
|
+
|
|
86
|
+
// ====================== Accessibility =======================
|
|
87
|
+
const [activeValueCells, setActiveValueCells] = (0, _useActive.default)(multiple, open);
|
|
88
|
+
|
|
89
|
+
// =========================== Path ===========================
|
|
90
|
+
const onPathOpen = nextValueCells => {
|
|
91
|
+
setActiveValueCells(nextValueCells);
|
|
92
|
+
|
|
93
|
+
// Trigger loadData
|
|
94
|
+
internalLoadData(nextValueCells);
|
|
95
|
+
};
|
|
96
|
+
const isSelectable = option => {
|
|
97
|
+
if (disabled) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const {
|
|
101
|
+
disabled: optionDisabled
|
|
102
|
+
} = option;
|
|
103
|
+
const isMergedLeaf = (0, _commonUtil.isLeaf)(option, fieldNames);
|
|
104
|
+
return !optionDisabled && (isMergedLeaf || changeOnSelect || multiple);
|
|
105
|
+
};
|
|
106
|
+
const onPathSelect = (valuePath, leaf, fromKeyboard = false) => {
|
|
107
|
+
onSelect(valuePath);
|
|
108
|
+
if (!multiple && (leaf || changeOnSelect && (expandTrigger === 'hover' || fromKeyboard))) {
|
|
109
|
+
toggleOpen(false);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// ========================== Option ==========================
|
|
114
|
+
const mergedOptions = React.useMemo(() => {
|
|
115
|
+
if (searchValue) {
|
|
116
|
+
return searchOptions;
|
|
117
|
+
}
|
|
118
|
+
return options;
|
|
119
|
+
}, [searchValue, searchOptions, options]);
|
|
120
|
+
|
|
121
|
+
// ========================== Column ==========================
|
|
122
|
+
const optionColumns = React.useMemo(() => {
|
|
123
|
+
const optionList = [{
|
|
124
|
+
options: mergedOptions
|
|
125
|
+
}];
|
|
126
|
+
let currentList = mergedOptions;
|
|
127
|
+
const fullPathKeys = (0, _commonUtil.getFullPathKeys)(currentList, fieldNames);
|
|
128
|
+
for (let i = 0; i < activeValueCells.length; i += 1) {
|
|
129
|
+
const activeValueCell = activeValueCells[i];
|
|
130
|
+
const currentOption = currentList.find((option, index) => (fullPathKeys[index] ? (0, _commonUtil.toPathKey)(fullPathKeys[index]) : option[fieldNames.value]) === activeValueCell);
|
|
131
|
+
const subOptions = currentOption?.[fieldNames.children];
|
|
132
|
+
if (!subOptions?.length) {
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
currentList = subOptions;
|
|
136
|
+
optionList.push({
|
|
137
|
+
options: subOptions
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return optionList;
|
|
141
|
+
}, [mergedOptions, activeValueCells, fieldNames]);
|
|
142
|
+
|
|
143
|
+
// ========================= Keyboard =========================
|
|
144
|
+
const onKeyboardSelect = (selectValueCells, option) => {
|
|
145
|
+
if (isSelectable(option)) {
|
|
146
|
+
onPathSelect(selectValueCells, (0, _commonUtil.isLeaf)(option, fieldNames), true);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
(0, _useKeyboard.default)(ref, mergedOptions, fieldNames, activeValueCells, onPathOpen, onKeyboardSelect, {
|
|
150
|
+
direction,
|
|
151
|
+
searchValue,
|
|
152
|
+
toggleOpen,
|
|
153
|
+
open
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// >>>>> Active Scroll
|
|
157
|
+
React.useEffect(() => {
|
|
158
|
+
if (searchValue) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
for (let i = 0; i < activeValueCells.length; i += 1) {
|
|
162
|
+
const cellPath = activeValueCells.slice(0, i + 1);
|
|
163
|
+
const cellKeyPath = (0, _commonUtil.toPathKey)(cellPath);
|
|
164
|
+
const ele = containerRef.current?.querySelector(`li[data-path-key="${cellKeyPath.replace(/\\{0,2}"/g, '\\"')}"]` // matches unescaped double quotes
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (ele) {
|
|
168
|
+
(0, _commonUtil.scrollIntoParentView)(ele);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}, [activeValueCells, searchValue]);
|
|
172
|
+
|
|
173
|
+
// ========================== Render ==========================
|
|
174
|
+
// >>>>> Empty
|
|
175
|
+
const isEmpty = !optionColumns[0]?.options?.length;
|
|
176
|
+
const emptyList = [{
|
|
177
|
+
[fieldNames.value]: '__EMPTY__',
|
|
178
|
+
[_Column.FIX_LABEL]: notFoundContent,
|
|
179
|
+
disabled: true
|
|
180
|
+
}];
|
|
181
|
+
const columnProps = {
|
|
182
|
+
...props,
|
|
183
|
+
multiple: !isEmpty && multiple,
|
|
184
|
+
onSelect: onPathSelect,
|
|
185
|
+
onActive: onPathOpen,
|
|
186
|
+
onToggleOpen: toggleOpen,
|
|
187
|
+
checkedSet,
|
|
188
|
+
halfCheckedSet,
|
|
189
|
+
loadingKeys,
|
|
190
|
+
isSelectable
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// >>>>> Columns
|
|
194
|
+
const mergedOptionColumns = isEmpty ? [{
|
|
195
|
+
options: emptyList
|
|
196
|
+
}] : optionColumns;
|
|
197
|
+
const columnNodes = mergedOptionColumns.map((col, index) => {
|
|
198
|
+
const prevValuePath = activeValueCells.slice(0, index);
|
|
199
|
+
const activeValue = activeValueCells[index];
|
|
200
|
+
return /*#__PURE__*/React.createElement(_Column.default, _extends({
|
|
201
|
+
key: index
|
|
202
|
+
}, columnProps, {
|
|
203
|
+
prefixCls: mergedPrefixCls,
|
|
204
|
+
options: col.options,
|
|
205
|
+
prevValuePath: prevValuePath,
|
|
206
|
+
activeValue: activeValue
|
|
207
|
+
}));
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// >>>>> Render
|
|
211
|
+
return /*#__PURE__*/React.createElement(_CacheContent.default, {
|
|
212
|
+
open: open
|
|
213
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
214
|
+
className: (0, _classnames.default)(`${mergedPrefixCls}-menus`, {
|
|
215
|
+
[`${mergedPrefixCls}-menu-empty`]: isEmpty,
|
|
216
|
+
[`${mergedPrefixCls}-rtl`]: rtl
|
|
217
|
+
}),
|
|
218
|
+
ref: containerRef
|
|
219
|
+
}, columnNodes));
|
|
220
|
+
});
|
|
221
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
222
|
+
RawOptionList.displayName = 'RawOptionList';
|
|
223
|
+
}
|
|
224
|
+
var _default = exports.default = RawOptionList;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _select = require("@rc-component/select");
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _List = _interopRequireDefault(require("./List"));
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
14
|
+
const RefOptionList = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
15
|
+
const baseProps = (0, _select.useBaseProps)();
|
|
16
|
+
|
|
17
|
+
// >>>>> Render
|
|
18
|
+
return /*#__PURE__*/React.createElement(_List.default, _extends({}, props, baseProps, {
|
|
19
|
+
ref: ref
|
|
20
|
+
}));
|
|
21
|
+
});
|
|
22
|
+
var _default = exports.default = RefOptionList;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _context = _interopRequireDefault(require("../context"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
/**
|
|
13
|
+
* Control the active open options path.
|
|
14
|
+
*/
|
|
15
|
+
const useActive = (multiple, open) => {
|
|
16
|
+
const {
|
|
17
|
+
values
|
|
18
|
+
} = React.useContext(_context.default);
|
|
19
|
+
const firstValueCells = values[0];
|
|
20
|
+
|
|
21
|
+
// Record current dropdown active options
|
|
22
|
+
// This also control the open status
|
|
23
|
+
const [activeValueCells, setActiveValueCells] = React.useState([]);
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
if (!multiple) {
|
|
26
|
+
setActiveValueCells(firstValueCells || []);
|
|
27
|
+
}
|
|
28
|
+
}, /* eslint-disable react-hooks/exhaustive-deps */
|
|
29
|
+
[open, firstValueCells]
|
|
30
|
+
/* eslint-enable react-hooks/exhaustive-deps */);
|
|
31
|
+
|
|
32
|
+
return [activeValueCells, setActiveValueCells];
|
|
33
|
+
};
|
|
34
|
+
var _default = exports.default = useActive;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RefOptionListProps } from '@rc-component/select/lib/OptionList';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import type { DefaultOptionType, InternalFieldNames, SingleValueType } from '../Cascader';
|
|
4
|
+
declare const _default: (ref: React.Ref<RefOptionListProps>, options: DefaultOptionType[], fieldNames: InternalFieldNames, activeValueCells: React.Key[], setActiveValueCells: (activeValueCells: React.Key[]) => void, onKeyBoardSelect: (valueCells: SingleValueType, option: DefaultOptionType) => void, contextProps: {
|
|
5
|
+
direction?: "ltr" | "rtl" | undefined;
|
|
6
|
+
searchValue: string;
|
|
7
|
+
toggleOpen: (open?: boolean) => void;
|
|
8
|
+
open?: boolean | undefined;
|
|
9
|
+
}) => void;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _KeyCode = _interopRequireDefault(require("@rc-component/util/lib/KeyCode"));
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
var _useSearchOptions = require("../hooks/useSearchOptions");
|
|
10
|
+
var _commonUtil = require("../utils/commonUtil");
|
|
11
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
var _default = (ref, options, fieldNames, activeValueCells, setActiveValueCells, onKeyBoardSelect, contextProps) => {
|
|
15
|
+
const {
|
|
16
|
+
direction,
|
|
17
|
+
searchValue,
|
|
18
|
+
toggleOpen,
|
|
19
|
+
open
|
|
20
|
+
} = contextProps;
|
|
21
|
+
const rtl = direction === 'rtl';
|
|
22
|
+
const [validActiveValueCells, lastActiveIndex, lastActiveOptions, fullPathKeys] = React.useMemo(() => {
|
|
23
|
+
let activeIndex = -1;
|
|
24
|
+
let currentOptions = options;
|
|
25
|
+
const mergedActiveIndexes = [];
|
|
26
|
+
const mergedActiveValueCells = [];
|
|
27
|
+
const len = activeValueCells.length;
|
|
28
|
+
const pathKeys = (0, _commonUtil.getFullPathKeys)(options, fieldNames);
|
|
29
|
+
|
|
30
|
+
// Fill validate active value cells and index
|
|
31
|
+
for (let i = 0; i < len && currentOptions; i += 1) {
|
|
32
|
+
// Mark the active index for current options
|
|
33
|
+
const nextActiveIndex = currentOptions.findIndex((option, index) => (pathKeys[index] ? (0, _commonUtil.toPathKey)(pathKeys[index]) : option[fieldNames.value]) === activeValueCells[i]);
|
|
34
|
+
if (nextActiveIndex === -1) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
activeIndex = nextActiveIndex;
|
|
38
|
+
mergedActiveIndexes.push(activeIndex);
|
|
39
|
+
mergedActiveValueCells.push(activeValueCells[i]);
|
|
40
|
+
currentOptions = currentOptions[activeIndex][fieldNames.children];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Fill last active options
|
|
44
|
+
let activeOptions = options;
|
|
45
|
+
for (let i = 0; i < mergedActiveIndexes.length - 1; i += 1) {
|
|
46
|
+
activeOptions = activeOptions[mergedActiveIndexes[i]][fieldNames.children];
|
|
47
|
+
}
|
|
48
|
+
return [mergedActiveValueCells, activeIndex, activeOptions, pathKeys];
|
|
49
|
+
}, [activeValueCells, fieldNames, options]);
|
|
50
|
+
|
|
51
|
+
// Update active value cells and scroll to target element
|
|
52
|
+
const internalSetActiveValueCells = next => {
|
|
53
|
+
setActiveValueCells(next);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Same options offset
|
|
57
|
+
const offsetActiveOption = offset => {
|
|
58
|
+
const len = lastActiveOptions.length;
|
|
59
|
+
let currentIndex = lastActiveIndex;
|
|
60
|
+
if (currentIndex === -1 && offset < 0) {
|
|
61
|
+
currentIndex = len;
|
|
62
|
+
}
|
|
63
|
+
for (let i = 0; i < len; i += 1) {
|
|
64
|
+
currentIndex = (currentIndex + offset + len) % len;
|
|
65
|
+
const option = lastActiveOptions[currentIndex];
|
|
66
|
+
if (option && !option.disabled) {
|
|
67
|
+
const nextActiveCells = validActiveValueCells.slice(0, -1).concat(fullPathKeys[currentIndex] ? (0, _commonUtil.toPathKey)(fullPathKeys[currentIndex]) : option[fieldNames.value]);
|
|
68
|
+
internalSetActiveValueCells(nextActiveCells);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Different options offset
|
|
75
|
+
const prevColumn = () => {
|
|
76
|
+
if (validActiveValueCells.length > 1) {
|
|
77
|
+
const nextActiveCells = validActiveValueCells.slice(0, -1);
|
|
78
|
+
internalSetActiveValueCells(nextActiveCells);
|
|
79
|
+
} else {
|
|
80
|
+
toggleOpen(false);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const nextColumn = () => {
|
|
84
|
+
const nextOptions = lastActiveOptions[lastActiveIndex]?.[fieldNames.children] || [];
|
|
85
|
+
const nextOption = nextOptions.find(option => !option.disabled);
|
|
86
|
+
if (nextOption) {
|
|
87
|
+
const nextActiveCells = [...validActiveValueCells, nextOption[fieldNames.value]];
|
|
88
|
+
internalSetActiveValueCells(nextActiveCells);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
React.useImperativeHandle(ref, () => ({
|
|
92
|
+
// scrollTo: treeRef.current?.scrollTo,
|
|
93
|
+
onKeyDown: event => {
|
|
94
|
+
const {
|
|
95
|
+
which
|
|
96
|
+
} = event;
|
|
97
|
+
switch (which) {
|
|
98
|
+
// >>> Arrow keys
|
|
99
|
+
case _KeyCode.default.UP:
|
|
100
|
+
case _KeyCode.default.DOWN:
|
|
101
|
+
{
|
|
102
|
+
let offset = 0;
|
|
103
|
+
if (which === _KeyCode.default.UP) {
|
|
104
|
+
offset = -1;
|
|
105
|
+
} else if (which === _KeyCode.default.DOWN) {
|
|
106
|
+
offset = 1;
|
|
107
|
+
}
|
|
108
|
+
if (offset !== 0) {
|
|
109
|
+
offsetActiveOption(offset);
|
|
110
|
+
}
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case _KeyCode.default.LEFT:
|
|
114
|
+
{
|
|
115
|
+
if (searchValue) {
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
if (rtl) {
|
|
119
|
+
nextColumn();
|
|
120
|
+
} else {
|
|
121
|
+
prevColumn();
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
case _KeyCode.default.RIGHT:
|
|
126
|
+
{
|
|
127
|
+
if (searchValue) {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (rtl) {
|
|
131
|
+
prevColumn();
|
|
132
|
+
} else {
|
|
133
|
+
nextColumn();
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case _KeyCode.default.BACKSPACE:
|
|
138
|
+
{
|
|
139
|
+
if (!searchValue) {
|
|
140
|
+
prevColumn();
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// >>> Select
|
|
146
|
+
case _KeyCode.default.ENTER:
|
|
147
|
+
{
|
|
148
|
+
if (validActiveValueCells.length) {
|
|
149
|
+
const option = lastActiveOptions[lastActiveIndex];
|
|
150
|
+
|
|
151
|
+
// Search option should revert back of origin options
|
|
152
|
+
const originOptions = option?.[_useSearchOptions.SEARCH_MARK] || [];
|
|
153
|
+
if (originOptions.length) {
|
|
154
|
+
onKeyBoardSelect(originOptions.map(opt => opt[fieldNames.value]), originOptions[originOptions.length - 1]);
|
|
155
|
+
} else {
|
|
156
|
+
onKeyBoardSelect(validActiveValueCells, lastActiveOptions[lastActiveIndex]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// >>> Close
|
|
163
|
+
case _KeyCode.default.ESC:
|
|
164
|
+
{
|
|
165
|
+
toggleOpen(false);
|
|
166
|
+
if (open) {
|
|
167
|
+
event.stopPropagation();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
onKeyUp: () => {}
|
|
173
|
+
}));
|
|
174
|
+
};
|
|
175
|
+
exports.default = _default;
|
package/lib/Panel.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { CascaderProps, DefaultOptionType } from './Cascader';
|
|
3
|
+
export type PickType = 'value' | 'defaultValue' | 'changeOnSelect' | 'onChange' | 'options' | 'prefixCls' | 'checkable' | 'fieldNames' | 'showCheckedStrategy' | 'loadData' | 'expandTrigger' | 'expandIcon' | 'loadingIcon' | 'className' | 'style' | 'direction' | 'notFoundContent' | 'disabled';
|
|
4
|
+
export type PanelProps<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType, Multiple extends boolean | React.ReactNode = false> = Pick<CascaderProps<OptionType, ValueField, Multiple>, PickType>;
|
|
5
|
+
export default function Panel<OptionType extends DefaultOptionType = DefaultOptionType, ValueField extends keyof OptionType = keyof OptionType, Multiple extends boolean | React.ReactNode = false>(props: PanelProps<OptionType, ValueField, Multiple>): React.JSX.Element;
|
package/lib/Panel.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = Panel;
|
|
7
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
8
|
+
var _util = require("@rc-component/util");
|
|
9
|
+
var React = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _context = _interopRequireDefault(require("./context"));
|
|
11
|
+
var _useMissingValues = _interopRequireDefault(require("./hooks/useMissingValues"));
|
|
12
|
+
var _useOptions = _interopRequireDefault(require("./hooks/useOptions"));
|
|
13
|
+
var _useSelect = _interopRequireDefault(require("./hooks/useSelect"));
|
|
14
|
+
var _useValues = _interopRequireDefault(require("./hooks/useValues"));
|
|
15
|
+
var _List = _interopRequireDefault(require("./OptionList/List"));
|
|
16
|
+
var _commonUtil = require("./utils/commonUtil");
|
|
17
|
+
var _treeUtil = require("./utils/treeUtil");
|
|
18
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
19
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
+
function noop() {}
|
|
22
|
+
function Panel(props) {
|
|
23
|
+
const {
|
|
24
|
+
prefixCls = 'rc-cascader',
|
|
25
|
+
style,
|
|
26
|
+
className,
|
|
27
|
+
options,
|
|
28
|
+
checkable,
|
|
29
|
+
defaultValue,
|
|
30
|
+
value,
|
|
31
|
+
fieldNames,
|
|
32
|
+
changeOnSelect,
|
|
33
|
+
onChange,
|
|
34
|
+
showCheckedStrategy,
|
|
35
|
+
loadData,
|
|
36
|
+
expandTrigger,
|
|
37
|
+
expandIcon = '>',
|
|
38
|
+
loadingIcon,
|
|
39
|
+
direction,
|
|
40
|
+
notFoundContent = 'Not Found',
|
|
41
|
+
disabled
|
|
42
|
+
} = props;
|
|
43
|
+
|
|
44
|
+
// ======================== Multiple ========================
|
|
45
|
+
const multiple = !!checkable;
|
|
46
|
+
|
|
47
|
+
// ========================= Values =========================
|
|
48
|
+
const [rawValues, setRawValues] = (0, _util.useMergedState)(defaultValue, {
|
|
49
|
+
value,
|
|
50
|
+
postState: _commonUtil.toRawValues
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ========================= FieldNames =========================
|
|
54
|
+
const mergedFieldNames = React.useMemo(() => (0, _commonUtil.fillFieldNames)(fieldNames), /* eslint-disable react-hooks/exhaustive-deps */
|
|
55
|
+
[JSON.stringify(fieldNames)]
|
|
56
|
+
/* eslint-enable react-hooks/exhaustive-deps */);
|
|
57
|
+
|
|
58
|
+
// =========================== Option ===========================
|
|
59
|
+
const [mergedOptions, getPathKeyEntities, getValueByKeyPath] = (0, _useOptions.default)(mergedFieldNames, options);
|
|
60
|
+
|
|
61
|
+
// ========================= Values =========================
|
|
62
|
+
const getMissingValues = (0, _useMissingValues.default)(mergedOptions, mergedFieldNames);
|
|
63
|
+
|
|
64
|
+
// Fill `rawValues` with checked conduction values
|
|
65
|
+
const [checkedValues, halfCheckedValues, missingCheckedValues] = (0, _useValues.default)(multiple, rawValues, getPathKeyEntities, getValueByKeyPath, getMissingValues);
|
|
66
|
+
|
|
67
|
+
// =========================== Change ===========================
|
|
68
|
+
const triggerChange = (0, _util.useEvent)(nextValues => {
|
|
69
|
+
setRawValues(nextValues);
|
|
70
|
+
|
|
71
|
+
// Save perf if no need trigger event
|
|
72
|
+
if (onChange) {
|
|
73
|
+
const nextRawValues = (0, _commonUtil.toRawValues)(nextValues);
|
|
74
|
+
const valueOptions = nextRawValues.map(valueCells => (0, _treeUtil.toPathOptions)(valueCells, mergedOptions, mergedFieldNames).map(valueOpt => valueOpt.option));
|
|
75
|
+
const triggerValues = multiple ? nextRawValues : nextRawValues[0];
|
|
76
|
+
const triggerOptions = multiple ? valueOptions : valueOptions[0];
|
|
77
|
+
onChange(triggerValues, triggerOptions);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// =========================== Select ===========================
|
|
82
|
+
const handleSelection = (0, _useSelect.default)(multiple, triggerChange, checkedValues, halfCheckedValues, missingCheckedValues, getPathKeyEntities, getValueByKeyPath, showCheckedStrategy);
|
|
83
|
+
const onInternalSelect = (0, _util.useEvent)(valuePath => {
|
|
84
|
+
handleSelection(valuePath);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// ======================== Context =========================
|
|
88
|
+
const cascaderContext = React.useMemo(() => ({
|
|
89
|
+
options: mergedOptions,
|
|
90
|
+
fieldNames: mergedFieldNames,
|
|
91
|
+
values: checkedValues,
|
|
92
|
+
halfValues: halfCheckedValues,
|
|
93
|
+
changeOnSelect,
|
|
94
|
+
onSelect: onInternalSelect,
|
|
95
|
+
checkable,
|
|
96
|
+
searchOptions: [],
|
|
97
|
+
dropdownPrefixCls: undefined,
|
|
98
|
+
loadData,
|
|
99
|
+
expandTrigger,
|
|
100
|
+
expandIcon,
|
|
101
|
+
loadingIcon,
|
|
102
|
+
dropdownMenuColumnStyle: undefined
|
|
103
|
+
}), [mergedOptions, mergedFieldNames, checkedValues, halfCheckedValues, changeOnSelect, onInternalSelect, checkable, loadData, expandTrigger, expandIcon, loadingIcon]);
|
|
104
|
+
|
|
105
|
+
// ========================= Render =========================
|
|
106
|
+
const panelPrefixCls = `${prefixCls}-panel`;
|
|
107
|
+
const isEmpty = !mergedOptions.length;
|
|
108
|
+
return /*#__PURE__*/React.createElement(_context.default.Provider, {
|
|
109
|
+
value: cascaderContext
|
|
110
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
111
|
+
className: (0, _classnames.default)(panelPrefixCls, {
|
|
112
|
+
[`${panelPrefixCls}-rtl`]: direction === 'rtl',
|
|
113
|
+
[`${panelPrefixCls}-empty`]: isEmpty
|
|
114
|
+
}, className),
|
|
115
|
+
style: style
|
|
116
|
+
}, isEmpty ? notFoundContent : /*#__PURE__*/React.createElement(_List.default, {
|
|
117
|
+
prefixCls: prefixCls,
|
|
118
|
+
searchValue: "",
|
|
119
|
+
multiple: multiple,
|
|
120
|
+
toggleOpen: noop,
|
|
121
|
+
open: true,
|
|
122
|
+
direction: direction,
|
|
123
|
+
disabled: disabled
|
|
124
|
+
})));
|
|
125
|
+
}
|
package/lib/context.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { CascaderProps, InternalFieldNames, DefaultOptionType, SingleValueType } from './Cascader';
|
|
3
|
+
export interface CascaderContextProps {
|
|
4
|
+
options: NonNullable<CascaderProps['options']>;
|
|
5
|
+
fieldNames: InternalFieldNames;
|
|
6
|
+
values: SingleValueType[];
|
|
7
|
+
halfValues: SingleValueType[];
|
|
8
|
+
changeOnSelect?: boolean;
|
|
9
|
+
onSelect: (valuePath: SingleValueType) => void;
|
|
10
|
+
checkable?: boolean | React.ReactNode;
|
|
11
|
+
searchOptions: DefaultOptionType[];
|
|
12
|
+
dropdownPrefixCls?: string;
|
|
13
|
+
loadData?: (selectOptions: DefaultOptionType[]) => void;
|
|
14
|
+
expandTrigger?: 'hover' | 'click';
|
|
15
|
+
expandIcon?: React.ReactNode;
|
|
16
|
+
loadingIcon?: React.ReactNode;
|
|
17
|
+
dropdownMenuColumnStyle?: React.CSSProperties;
|
|
18
|
+
optionRender?: CascaderProps['optionRender'];
|
|
19
|
+
}
|
|
20
|
+
declare const CascaderContext: React.Context<CascaderContextProps>;
|
|
21
|
+
export default CascaderContext;
|
package/lib/context.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
9
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
|
+
const CascaderContext = /*#__PURE__*/React.createContext({});
|
|
11
|
+
var _default = exports.default = CascaderContext;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { DefaultOptionType, SingleValueType, CascaderProps, InternalFieldNames } from '../Cascader';
|
|
3
|
+
declare const _default: (rawValues: SingleValueType[], options: DefaultOptionType[], fieldNames: InternalFieldNames, multiple: boolean, displayRender: CascaderProps['displayRender']) => {
|
|
4
|
+
label: React.ReactNode;
|
|
5
|
+
value: string;
|
|
6
|
+
key: string;
|
|
7
|
+
valueCells: SingleValueType;
|
|
8
|
+
disabled: boolean | undefined;
|
|
9
|
+
}[];
|
|
10
|
+
export default _default;
|