@canlooks/can-ui 0.0.127 → 0.0.129
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/dist/cjs/components/app/app.js +8 -4
- package/dist/cjs/components/cascade/cascade.style.d.ts +1 -1
- package/dist/cjs/components/dataGrid/dataGridRows.js +2 -4
- package/dist/cjs/components/inputBase/inputBase.js +1 -1
- package/dist/cjs/components/optionsBase/optionsBase.js +24 -23
- package/dist/cjs/components/select/select.d.ts +7 -25
- package/dist/cjs/components/select/select.js +31 -107
- package/dist/cjs/components/selectBase/index.d.ts +1 -0
- package/dist/cjs/components/selectBase/index.js +4 -0
- package/dist/cjs/components/selectBase/selectBase.d.ts +41 -0
- package/dist/cjs/components/selectBase/selectBase.js +101 -0
- package/dist/cjs/components/{treeSelect/treeSelect.style.js → selectBase/selectBase.style.js} +3 -3
- package/dist/cjs/components/selectionContext/selectionContext.d.ts +1 -2
- package/dist/cjs/components/selectionContext/selectionHook.d.ts +6 -8
- package/dist/cjs/components/selectionContext/selectionHook.js +8 -11
- package/dist/cjs/components/tag/tag.js +2 -2
- package/dist/cjs/components/tree/tree.d.ts +3 -1
- package/dist/cjs/components/tree/tree.js +2 -2
- package/dist/cjs/components/tree/treeNode.js +1 -1
- package/dist/cjs/components/treeSelect/treeSelect.d.ts +8 -24
- package/dist/cjs/components/treeSelect/treeSelect.js +53 -51
- package/dist/esm/components/app/app.js +8 -4
- package/dist/esm/components/cascade/cascade.style.d.ts +1 -1
- package/dist/esm/components/dataGrid/dataGridRows.js +2 -4
- package/dist/esm/components/inputBase/inputBase.js +1 -1
- package/dist/esm/components/optionsBase/optionsBase.js +24 -23
- package/dist/esm/components/select/select.d.ts +7 -25
- package/dist/esm/components/select/select.js +33 -109
- package/dist/esm/components/selectBase/index.d.ts +1 -0
- package/dist/esm/components/selectBase/index.js +1 -0
- package/dist/esm/components/selectBase/selectBase.d.ts +41 -0
- package/dist/esm/components/selectBase/selectBase.js +98 -0
- package/dist/esm/components/{select/select.style.js → selectBase/selectBase.style.js} +13 -13
- package/dist/esm/components/selectionContext/selectionContext.d.ts +1 -2
- package/dist/esm/components/selectionContext/selectionHook.d.ts +6 -8
- package/dist/esm/components/selectionContext/selectionHook.js +8 -11
- package/dist/esm/components/tag/tag.js +2 -2
- package/dist/esm/components/tree/tree.d.ts +3 -1
- package/dist/esm/components/tree/tree.js +2 -2
- package/dist/esm/components/tree/treeNode.js +1 -1
- package/dist/esm/components/treeSelect/treeSelect.d.ts +8 -24
- package/dist/esm/components/treeSelect/treeSelect.js +54 -52
- package/documentation/dist/assets/{index-kzMR4-bu.js → index-DyrGMYuH.js} +879 -926
- package/documentation/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/cjs/components/select/select.style.js +0 -61
- package/dist/cjs/components/treeSelect/treeSelect.style.d.ts +0 -10
- package/dist/esm/components/treeSelect/treeSelect.style.d.ts +0 -10
- package/dist/esm/components/treeSelect/treeSelect.style.js +0 -58
- package/dist/cjs/components/{select/select.style.d.ts → selectBase/selectBase.style.d.ts} +1 -1
- package/dist/esm/components/{select/select.style.d.ts → selectBase/selectBase.style.d.ts} +1 -1
|
@@ -28,11 +28,15 @@ exports.App = (({ theme, ...props }) => {
|
|
|
28
28
|
});
|
|
29
29
|
function InnerApp({ component: Component = 'div', theme, children, fill = true, ...props }) {
|
|
30
30
|
const appValue = (0, utils_1.useExternalClass)(() => ({
|
|
31
|
-
dialog:
|
|
32
|
-
message:
|
|
33
|
-
notification:
|
|
34
|
-
actionSheet:
|
|
31
|
+
dialog: new appDialog_1.AppDialogMethods(),
|
|
32
|
+
message: new appMessage_1.AppMessageMethods(),
|
|
33
|
+
notification: new appNotification_1.AppNotificationMethods(),
|
|
34
|
+
actionSheet: new appActionSheet_1.AppActionSheetMethods()
|
|
35
35
|
}));
|
|
36
|
+
exports.App.dialog ||= appValue.dialog;
|
|
37
|
+
exports.App.message ||= appValue.message;
|
|
38
|
+
exports.App.notification ||= appValue.notification;
|
|
39
|
+
exports.App.actionSheet ||= appValue.actionSheet;
|
|
36
40
|
return ((0, jsx_runtime_1.jsxs)(AppContext, { value: appValue, children: [Component
|
|
37
41
|
? (0, jsx_runtime_1.jsx)(Component, { ...props, css: [
|
|
38
42
|
app_style_1.style,
|
|
@@ -36,7 +36,7 @@ exports.DataGridRows = (0, react_2.memo)(({ rows, _level = 0 }) => {
|
|
|
36
36
|
(0, react_1.createElement)(Tr, { ...(0, utils_1.mergeComponentProps)(TrProps, _rowProps, {
|
|
37
37
|
className: (0, utils_1.clsx)(_rowProps, _level > 0 && dataGrid_style_1.classes.sub),
|
|
38
38
|
onClick() {
|
|
39
|
-
clickRowToSelect && toggleSelected(trKey
|
|
39
|
+
clickRowToSelect && toggleSelected(trKey);
|
|
40
40
|
}
|
|
41
41
|
}), key: trKey, "data-selected": status === 2 }, flattedColumns?.flatMap((col, j) => {
|
|
42
42
|
if (typeof col === 'symbol') {
|
|
@@ -50,9 +50,7 @@ exports.DataGridRows = (0, react_2.memo)(({ rows, _level = 0 }) => {
|
|
|
50
50
|
expandableIndex = j;
|
|
51
51
|
}
|
|
52
52
|
const Component = multiple ? checkbox_1.Checkbox : radio_1.Radio;
|
|
53
|
-
return ((0, jsx_runtime_1.jsx)(table_1.TdCell, { className: dataGrid_style_1.classes.selectable, sticky: j === 0 ? 'left' : void 0, children: (0, jsx_runtime_1.jsx)(Component, { checked: status === 2, indeterminate: status === 1, onChange: () =>
|
|
54
|
-
toggleSelected(trKey, row);
|
|
55
|
-
}, onClick: e => e.stopPropagation() }) }, j + '_selectable'));
|
|
53
|
+
return ((0, jsx_runtime_1.jsx)(table_1.TdCell, { className: dataGrid_style_1.classes.selectable, sticky: j === 0 ? 'left' : void 0, children: (0, jsx_runtime_1.jsx)(Component, { checked: status === 2, indeterminate: status === 1, onChange: () => toggleSelected(trKey), onClick: e => e.stopPropagation() }) }, j + '_selectable'));
|
|
56
54
|
}
|
|
57
55
|
const {
|
|
58
56
|
// 排除无需加入dom节点的属性
|
|
@@ -10,7 +10,7 @@ const button_1 = require("../button");
|
|
|
10
10
|
const loadingIndicator_1 = require("../loadingIndicator");
|
|
11
11
|
const icon_1 = require("../icon");
|
|
12
12
|
const faCircleXmark_1 = require("@fortawesome/free-solid-svg-icons/faCircleXmark");
|
|
13
|
-
exports.InputBase = (({ ref, variant = 'outlined', size, shape, color = 'primary', children, prefix, suffix, onClear, loading, type, clearable = type !== 'number',
|
|
13
|
+
exports.InputBase = (({ ref, variant = 'outlined', size = 'medium', shape = 'square', color = 'primary', children, prefix, suffix, onClear, loading = false, type, clearable = type !== 'number',
|
|
14
14
|
// 以下属性传递给<input/>
|
|
15
15
|
min, max, step, precision, placeholder, disabled, readOnly, autoFocus, defaultValue, value, onChange, ...props }) => {
|
|
16
16
|
const innerRef = (0, react_1.useRef)(null);
|
|
@@ -74,46 +74,47 @@ searchValue, selectedValue, onToggleSelected, ...props }) => {
|
|
|
74
74
|
if (!filteredOptions?.length) {
|
|
75
75
|
return (0, jsx_runtime_1.jsx)(placeholder_1.Placeholder, {});
|
|
76
76
|
}
|
|
77
|
-
const makeProps = (params) =>
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
: params.label
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
77
|
+
const makeProps = (params) => {
|
|
78
|
+
return (0, utils_1.mergeComponentProps)(params.option, {
|
|
79
|
+
ref: params.scrollHere || params.selected ? selectedItemRef : void 0,
|
|
80
|
+
showCheckbox,
|
|
81
|
+
selected: params.selected,
|
|
82
|
+
focused: verticalIndex.current === params.index,
|
|
83
|
+
value: params.value,
|
|
84
|
+
label: typeof params.label === 'string' && searchValue
|
|
85
|
+
? (0, jsx_runtime_1.jsx)(highlight_1.Highlight, { keywords: searchValue?.split(' '), children: params.label })
|
|
86
|
+
: params.label,
|
|
87
|
+
onClick: e => {
|
|
88
|
+
e.stopPropagation();
|
|
89
|
+
syncOnToggleSelected.current?.(params.value, e);
|
|
90
|
+
},
|
|
91
|
+
onPointerEnter: () => {
|
|
92
|
+
setVerticalIndex(-1);
|
|
93
|
+
},
|
|
94
|
+
children: null
|
|
95
|
+
});
|
|
96
|
+
};
|
|
96
97
|
if (options) {
|
|
97
98
|
return filteredOptions.map((opt, index) => {
|
|
98
99
|
const value = opt[primaryKey];
|
|
99
100
|
const label = opt[labelKey] ?? value;
|
|
100
|
-
return ((0, jsx_runtime_1.jsx)(menuItem_1.MenuItem, {
|
|
101
|
+
return ((0, jsx_runtime_1.jsx)(menuItem_1.MenuItem, { ...makeProps({
|
|
102
|
+
option: opt,
|
|
101
103
|
label,
|
|
102
104
|
value,
|
|
103
105
|
index,
|
|
104
106
|
selected: (0, utils_1.isSelected)(value, selectedValue),
|
|
105
107
|
scrollHere: opt.scrollHere
|
|
106
|
-
})
|
|
108
|
+
}) }, opt.key ?? value ?? index));
|
|
107
109
|
});
|
|
108
110
|
}
|
|
109
|
-
// children
|
|
110
111
|
return filteredOptions.map((c, index) => {
|
|
111
112
|
if (!(0, react_1.isValidElement)(c)) {
|
|
112
113
|
return c;
|
|
113
114
|
}
|
|
114
115
|
const { value, label, scrollHere } = c.props;
|
|
115
116
|
return (0, react_1.cloneElement)(c, makeProps({
|
|
116
|
-
|
|
117
|
+
option: c.props,
|
|
117
118
|
label,
|
|
118
119
|
value: value,
|
|
119
120
|
index,
|
|
@@ -1,31 +1,13 @@
|
|
|
1
|
-
import { ReactElement
|
|
2
|
-
import {
|
|
3
|
-
import { PopperProps, PopperRef } from '../popper';
|
|
4
|
-
import { MenuItem } from '../menuItem';
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { SelectBaseMultipleProps, SelectBaseOwnProps, SelectBaseSingleProps } from '../selectBase';
|
|
5
3
|
import { MenuOptionType, OptionsBaseSharedProps } from '../optionsBase';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
export interface
|
|
9
|
-
/** <select />内部由<input />实现 */
|
|
10
|
-
inputProps?: ComponentProps<'input'>;
|
|
11
|
-
popperProps?: PopperProps;
|
|
12
|
-
popperRef?: Ref<PopperRef>;
|
|
13
|
-
defaultOpen?: boolean;
|
|
14
|
-
open?: boolean;
|
|
15
|
-
onOpenChange?(open: boolean): void;
|
|
16
|
-
sizeAdaptable?: boolean;
|
|
17
|
-
children?: ReactNode;
|
|
18
|
-
searchable?: boolean;
|
|
19
|
-
defaultSearchValue?: string;
|
|
20
|
-
searchValue?: string;
|
|
21
|
-
onSearchChange?(searchValue: string): void;
|
|
22
|
-
searchInputProps?: InputProps;
|
|
4
|
+
import { Id } from '../../types';
|
|
5
|
+
import { MenuItem } from '../menuItem';
|
|
6
|
+
export interface SelectOwnProps<O extends MenuOptionType> extends SelectBaseOwnProps, OptionsBaseSharedProps<O> {
|
|
23
7
|
}
|
|
24
|
-
export interface SelectSingleProps<O extends MenuOptionType, V extends Id = Id> extends
|
|
25
|
-
renderBackfill?(selectedValue: V): ReactNode;
|
|
8
|
+
export interface SelectSingleProps<O extends MenuOptionType, V extends Id = Id> extends SelectOwnProps<O>, SelectBaseSingleProps<V> {
|
|
26
9
|
}
|
|
27
|
-
export interface SelectMultipleProps<O extends MenuOptionType, V extends Id = Id> extends
|
|
28
|
-
renderBackfill?(selectedValue: V[]): ReactNode;
|
|
10
|
+
export interface SelectMultipleProps<O extends MenuOptionType, V extends Id = Id> extends SelectOwnProps<O>, SelectBaseMultipleProps<V> {
|
|
29
11
|
}
|
|
30
12
|
export type SelectProps<O extends MenuOptionType, V extends Id = Id> = SelectSingleProps<O, V> | SelectMultipleProps<O, V>;
|
|
31
13
|
export declare const Select: {
|
|
@@ -3,66 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Option = exports.Select = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
|
-
const
|
|
7
|
-
const utils_1 = require("../../utils");
|
|
8
|
-
const select_style_1 = require("./select.style");
|
|
9
|
-
const popper_1 = require("../popper");
|
|
10
|
-
const menuItem_1 = require("../menuItem");
|
|
11
|
-
const tag_1 = require("../tag");
|
|
6
|
+
const selectBase_1 = require("../selectBase");
|
|
12
7
|
const optionsBase_1 = require("../optionsBase");
|
|
13
|
-
const
|
|
14
|
-
const loadingIndicator_1 = require("../loadingIndicator");
|
|
8
|
+
const menuItem_1 = require("../menuItem");
|
|
15
9
|
const selectionContext_1 = require("../selectionContext");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
_setInnerOpen(open);
|
|
26
|
-
if (!open && document.activeElement === searchInputRef.current) {
|
|
27
|
-
// 关闭下拉框时,如果焦点在搜索框上,需要移除焦点,避免影响下次打开下拉框
|
|
28
|
-
searchInputRef.current.blur();
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
const openChangeHandler = (open) => {
|
|
32
|
-
setInnerOpen(open);
|
|
33
|
-
};
|
|
34
|
-
const openChangeEnd = (open) => {
|
|
35
|
-
// 关闭动画结束后清空搜索框
|
|
36
|
-
!open && setInnerSearchValue('');
|
|
37
|
-
};
|
|
38
|
-
const searchInputRef = (0, react_1.useRef)(null);
|
|
39
|
-
const onBlur = () => {
|
|
40
|
-
setTimeout(() => {
|
|
41
|
-
// 失去焦点后,如果不是聚焦在搜索框,则需要关闭弹框
|
|
42
|
-
searchInputRef.current !== document.activeElement && setInnerOpen(false);
|
|
43
|
-
});
|
|
44
|
-
};
|
|
45
|
-
const [innerValue, _toggleSelected, setInnerValue] = (0, selectionContext_1.useFlatSelection)({ multiple, defaultValue, value, onChange });
|
|
46
|
-
const onToggleSelected = (0, react_1.useCallback)((value) => {
|
|
47
|
-
_toggleSelected(value);
|
|
48
|
-
// 单选模式下,选中一次就自动关闭弹框
|
|
49
|
-
!multiple && setInnerOpen(false);
|
|
50
|
-
}, [multiple]);
|
|
51
|
-
const onClear = () => {
|
|
52
|
-
props.onClear?.();
|
|
53
|
-
setInnerValue(multiple ? [] : void 0);
|
|
54
|
-
};
|
|
55
|
-
/**
|
|
56
|
-
* ------------------------------------------------------------------
|
|
57
|
-
* 搜索
|
|
58
|
-
*/
|
|
59
|
-
const [innerSearchValue, setInnerSearchValue] = (0, utils_1.useControlled)(defaultSearchValue, searchValue, onSearchChange);
|
|
60
|
-
const deferredSearchValue = (0, react_1.useDeferredValue)(innerSearchValue.current);
|
|
61
|
-
/**
|
|
62
|
-
* ------------------------------------------------------------------
|
|
63
|
-
* 渲染部分
|
|
64
|
-
*/
|
|
65
|
-
const optionsArr = options || react_1.Children.map(children, c => (0, react_1.isValidElement)(c) ? c.props : c) || void 0;
|
|
10
|
+
exports.Select = (0, react_1.memo)(({ children,
|
|
11
|
+
// 从SelectableProps继承
|
|
12
|
+
multiple = false, // 同时转发至<SelectBase/>
|
|
13
|
+
defaultValue, value, onChange, renderBackfill, // 同时转发至<SelectBase/>
|
|
14
|
+
// 从OptionsBaseSharedProps继承
|
|
15
|
+
showCheckbox = multiple, loading = false, options, labelKey = 'label', primaryKey = 'value', searchTokenKey = 'searchToken', filterPredicate, ...props }) => {
|
|
16
|
+
const optionsArr = options || react_1.Children.map(children, c => {
|
|
17
|
+
return (0, react_1.isValidElement)(c) ? c.props : c;
|
|
18
|
+
}) || void 0;
|
|
66
19
|
const optionsMap = (0, react_1.useMemo)(() => {
|
|
67
20
|
const map = new Map();
|
|
68
21
|
optionsArr?.forEach(opt => {
|
|
@@ -70,55 +23,26 @@ showCheckbox = !!multiple, loading, options, labelKey = 'label', primaryKey = 'v
|
|
|
70
23
|
});
|
|
71
24
|
return map;
|
|
72
25
|
}, [optionsArr, primaryKey]);
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (multiple) {
|
|
78
|
-
return innerValue?.map((v) => (0, jsx_runtime_1.jsx)(tag_1.Tag, { closable: true, onClose: () => onToggleSelected(v), children: optionsMap.get(v)?.[labelKey] ?? v }, v));
|
|
79
|
-
}
|
|
80
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: select_style_1.classes.backfillWrap, children: optionsMap.get(innerValue)?.[labelKey] ?? innerValue }));
|
|
26
|
+
const [innerValue, toggleSelected, setInnerValue] = (0, selectionContext_1.useFlatSelection)({ multiple, defaultValue, value, onChange });
|
|
27
|
+
const onClear = () => {
|
|
28
|
+
props.onClear?.();
|
|
29
|
+
setInnerValue(multiple ? [] : void 0);
|
|
81
30
|
};
|
|
82
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
onBlur
|
|
99
|
-
}) }), (0, jsx_runtime_1.jsx)(optionsBase_1.OptionsBase, { selectedValue: innerValue, searchValue: deferredSearchValue, onToggleSelected,
|
|
100
|
-
showCheckbox,
|
|
101
|
-
loading,
|
|
102
|
-
options,
|
|
103
|
-
labelKey,
|
|
104
|
-
primaryKey,
|
|
105
|
-
searchTokenKey,
|
|
106
|
-
filterPredicate, children: children })] }))
|
|
107
|
-
}, popperProps, {
|
|
108
|
-
popperRef,
|
|
109
|
-
onOpenChange: openChangeHandler,
|
|
110
|
-
onOpenChangeEnd: openChangeEnd,
|
|
111
|
-
onPointerDown: e => e.preventDefault()
|
|
112
|
-
}), children: (0, jsx_runtime_1.jsx)(inputBase_1.InputBase, { clearable: !!multiple, ...(0, utils_1.mergeComponentProps)(props, {
|
|
113
|
-
css: select_style_1.style,
|
|
114
|
-
className: select_style_1.classes.root,
|
|
115
|
-
value: innerValue,
|
|
116
|
-
onClear,
|
|
117
|
-
onBlur
|
|
118
|
-
}), "data-focused": innerOpen.current, children: inputBaseProps => (0, jsx_runtime_1.jsxs)("div", { className: select_style_1.classes.contentWrap, children: [(0, utils_1.isNoValue)(innerValue)
|
|
119
|
-
? (0, jsx_runtime_1.jsx)("div", { className: select_style_1.classes.placeholder, children: props.placeholder ?? '请选择' })
|
|
120
|
-
: (0, jsx_runtime_1.jsx)("div", { className: select_style_1.classes.backfill, children: renderBackfillFn() }), (0, jsx_runtime_1.jsx)("input", { size: 1, ...(0, utils_1.mergeComponentProps)(inputBaseProps, inputProps), "data-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: select_style_1.classes.arrow, "data-open": innerOpen.current, children: loading
|
|
121
|
-
? (0, jsx_runtime_1.jsx)(loadingIndicator_1.LoadingIndicator, {})
|
|
122
|
-
: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faChevronDown_1.faChevronDown }) })] }) }) }));
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(selectBase_1.SelectBase, { ...props, multiple: multiple, renderBackfill: renderBackfill, onClear: onClear, _internalProps: {
|
|
32
|
+
labelKey,
|
|
33
|
+
optionsMap,
|
|
34
|
+
innerValue,
|
|
35
|
+
onToggleSelected: toggleSelected,
|
|
36
|
+
renderPopperContent: (searchValue, onToggleSelected) => ((0, jsx_runtime_1.jsx)(optionsBase_1.OptionsBase, { selectedValue: innerValue, searchValue,
|
|
37
|
+
onToggleSelected,
|
|
38
|
+
showCheckbox,
|
|
39
|
+
loading,
|
|
40
|
+
options,
|
|
41
|
+
labelKey,
|
|
42
|
+
primaryKey,
|
|
43
|
+
searchTokenKey,
|
|
44
|
+
filterPredicate,
|
|
45
|
+
children }))
|
|
46
|
+
} }));
|
|
123
47
|
});
|
|
124
48
|
exports.Option = exports.Select.Option = menuItem_1.MenuItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './selectBase';
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { InputBaseProps } from '../inputBase';
|
|
2
|
+
import { ComponentProps, ReactNode, Ref } from 'react';
|
|
3
|
+
import { PopperProps, PopperRef } from '../popper';
|
|
4
|
+
import { InputProps } from '../input';
|
|
5
|
+
import { Id, SelectableMultipleProps, SelectableSingleProps } from '../../types';
|
|
6
|
+
export interface SelectBaseOwnProps extends Omit<InputBaseProps<'input'>, 'children' | 'placeholder' | 'defaultValue' | 'value' | 'onChange' | 'onToggle'> {
|
|
7
|
+
/** <select />内部由<input />实现 */
|
|
8
|
+
inputProps?: ComponentProps<'input'>;
|
|
9
|
+
popperProps?: PopperProps;
|
|
10
|
+
popperRef?: Ref<PopperRef>;
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
open?: boolean;
|
|
13
|
+
onOpenChange?(open: boolean): void;
|
|
14
|
+
placeholder?: ReactNode;
|
|
15
|
+
sizeAdaptable?: boolean;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
readOnly?: boolean;
|
|
18
|
+
loading?: boolean;
|
|
19
|
+
searchable?: boolean;
|
|
20
|
+
defaultSearchValue?: string;
|
|
21
|
+
searchValue?: string;
|
|
22
|
+
onSearchChange?(searchValue: string): void;
|
|
23
|
+
searchInputProps?: InputProps;
|
|
24
|
+
}
|
|
25
|
+
export interface SelectBaseSingleProps<V extends Id = Id> extends SelectBaseOwnProps, SelectableSingleProps<V> {
|
|
26
|
+
renderBackfill?(selectedValue: V | undefined): ReactNode;
|
|
27
|
+
}
|
|
28
|
+
export interface SelectBaseMultipleProps<V extends Id = Id> extends SelectBaseOwnProps, SelectableMultipleProps<V> {
|
|
29
|
+
renderBackfill?(selectedValue: V[] | undefined): ReactNode;
|
|
30
|
+
}
|
|
31
|
+
export type SelectBaseProps<V extends Id = Id> = SelectBaseSingleProps<V> | SelectBaseMultipleProps<V>;
|
|
32
|
+
export declare function SelectBase({ inputProps, popperProps, popperRef, defaultOpen, open, onOpenChange, placeholder, sizeAdaptable, disabled, readOnly, loading, searchable, defaultSearchValue, searchValue, onSearchChange, searchInputProps, multiple, renderBackfill, _internalProps: { labelKey, optionsMap, innerValue, onToggleSelected, renderPopperContent }, ...props }: Omit<SelectBaseProps, 'defaultValue' | 'value' | 'onChange'> & {
|
|
33
|
+
/** @private 内部使用的属性 */
|
|
34
|
+
_internalProps: {
|
|
35
|
+
labelKey: keyof any;
|
|
36
|
+
optionsMap: Map<Id, any>;
|
|
37
|
+
innerValue: (Id & Id[]) | undefined;
|
|
38
|
+
onToggleSelected(value: Id): void;
|
|
39
|
+
renderPopperContent(searchValue: string, toggleSelected: (value: Id) => void): ReactNode;
|
|
40
|
+
};
|
|
41
|
+
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SelectBase = SelectBase;
|
|
4
|
+
const jsx_runtime_1 = require("@emotion/react/jsx-runtime");
|
|
5
|
+
const inputBase_1 = require("../inputBase");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const popper_1 = require("../popper");
|
|
8
|
+
const input_1 = require("../input");
|
|
9
|
+
const utils_1 = require("../../utils");
|
|
10
|
+
const popper_style_1 = require("../popper/popper.style");
|
|
11
|
+
const icon_1 = require("../icon");
|
|
12
|
+
const faMagnifyingGlass_1 = require("@fortawesome/free-solid-svg-icons/faMagnifyingGlass");
|
|
13
|
+
const selectBase_style_1 = require("./selectBase.style");
|
|
14
|
+
const tag_1 = require("../tag");
|
|
15
|
+
const loadingIndicator_1 = require("../loadingIndicator");
|
|
16
|
+
const faChevronDown_1 = require("@fortawesome/free-solid-svg-icons/faChevronDown");
|
|
17
|
+
function SelectBase({ inputProps, popperProps, popperRef, defaultOpen = false, open, onOpenChange, placeholder = '请选择', sizeAdaptable = true, disabled, readOnly, loading = false, searchable, defaultSearchValue = '', searchValue, onSearchChange, searchInputProps,
|
|
18
|
+
// 从SelectableProps继承
|
|
19
|
+
multiple = false, renderBackfill, _internalProps: { labelKey, optionsMap, innerValue, onToggleSelected, renderPopperContent }, ...props }) {
|
|
20
|
+
const [innerOpen, _setInnerOpen] = (0, utils_1.useControlled)(defaultOpen, open, onOpenChange);
|
|
21
|
+
const setInnerOpen = (open) => {
|
|
22
|
+
_setInnerOpen(open);
|
|
23
|
+
if (!open && document.activeElement === searchInputRef.current) {
|
|
24
|
+
// 关闭下拉框时,如果焦点在搜索框上,需要移除焦点,避免影响下次打开下拉框
|
|
25
|
+
searchInputRef.current.blur();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const openChangeHandler = (open) => {
|
|
29
|
+
setInnerOpen(open);
|
|
30
|
+
};
|
|
31
|
+
const openChangeEnd = (open) => {
|
|
32
|
+
// 关闭动画结束后清空搜索框
|
|
33
|
+
!open && setInnerSearchValue('');
|
|
34
|
+
};
|
|
35
|
+
const toggleSelectHandler = (value) => {
|
|
36
|
+
onToggleSelected(value);
|
|
37
|
+
// 单选模式下,选中一次就自动关闭弹框
|
|
38
|
+
!multiple && setInnerOpen(false);
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* ------------------------------------------------------------------
|
|
42
|
+
* 搜索
|
|
43
|
+
*/
|
|
44
|
+
const searchInputRef = (0, react_1.useRef)(null);
|
|
45
|
+
const [innerSearchValue, setInnerSearchValue] = (0, utils_1.useControlled)(defaultSearchValue, searchValue, onSearchChange);
|
|
46
|
+
const deferredSearchValue = (0, react_1.useDeferredValue)(innerSearchValue.current);
|
|
47
|
+
/**
|
|
48
|
+
* ------------------------------------------------------------------
|
|
49
|
+
* 渲染部分
|
|
50
|
+
*/
|
|
51
|
+
const onBlur = () => {
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
// 失去焦点后,如果不是聚焦在搜索框,则需要关闭弹框
|
|
54
|
+
searchInputRef.current !== document.activeElement && setInnerOpen(false);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const renderBackfillFn = () => {
|
|
58
|
+
if (renderBackfill) {
|
|
59
|
+
return renderBackfill(innerValue);
|
|
60
|
+
}
|
|
61
|
+
if (multiple) {
|
|
62
|
+
return innerValue?.map(v => (0, jsx_runtime_1.jsx)(tag_1.Tag, { closable: true, onClose: () => toggleSelectHandler(v), children: optionsMap.get(v)?.[labelKey] ?? v }, v));
|
|
63
|
+
}
|
|
64
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: selectBase_style_1.classes.backfillWrap, children: optionsMap.get(innerValue)?.[labelKey] ?? innerValue }));
|
|
65
|
+
};
|
|
66
|
+
return ((0, jsx_runtime_1.jsx)(popper_1.Popper, { ...(0, utils_1.mergeComponentProps)({
|
|
67
|
+
css: popper_style_1.popperStyle,
|
|
68
|
+
open: innerOpen.current,
|
|
69
|
+
placement: 'bottom',
|
|
70
|
+
variant: 'collapse',
|
|
71
|
+
trigger: ['click', 'enter'],
|
|
72
|
+
disabled: disabled || readOnly,
|
|
73
|
+
sizeAdaptable: sizeAdaptable,
|
|
74
|
+
content: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [searchable &&
|
|
75
|
+
(0, jsx_runtime_1.jsx)(input_1.Input, { ...(0, utils_1.mergeComponentProps)({
|
|
76
|
+
inputProps: (0, utils_1.mergeComponentProps)(searchInputProps?.inputProps, { ref: searchInputRef }),
|
|
77
|
+
prefix: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faMagnifyingGlass_1.faMagnifyingGlass }),
|
|
78
|
+
placeholder: '搜索',
|
|
79
|
+
value: innerSearchValue.current
|
|
80
|
+
}, searchInputProps, {
|
|
81
|
+
onChange: e => setInnerSearchValue(e.target.value),
|
|
82
|
+
onBlur
|
|
83
|
+
}) }), renderPopperContent(deferredSearchValue, toggleSelectHandler)] }))
|
|
84
|
+
}, popperProps, {
|
|
85
|
+
popperRef,
|
|
86
|
+
onOpenChange: openChangeHandler,
|
|
87
|
+
onOpenChangeEnd: openChangeEnd,
|
|
88
|
+
onPointerDown: e => e.preventDefault()
|
|
89
|
+
}), children: (0, jsx_runtime_1.jsx)(inputBase_1.InputBase, { clearable: multiple, ...(0, utils_1.mergeComponentProps)(props, {
|
|
90
|
+
css: selectBase_style_1.style,
|
|
91
|
+
className: selectBase_style_1.classes.root,
|
|
92
|
+
disabled,
|
|
93
|
+
readOnly,
|
|
94
|
+
value: innerValue,
|
|
95
|
+
onBlur
|
|
96
|
+
}), "data-focused": innerOpen.current, children: inputBaseProps => (0, jsx_runtime_1.jsxs)("div", { className: selectBase_style_1.classes.contentWrap, children: [(0, utils_1.isNoValue)(innerValue)
|
|
97
|
+
? (0, jsx_runtime_1.jsx)("div", { className: selectBase_style_1.classes.placeholder, children: placeholder })
|
|
98
|
+
: (0, jsx_runtime_1.jsx)("div", { className: selectBase_style_1.classes.backfill, children: renderBackfillFn() }), (0, jsx_runtime_1.jsx)("input", { size: 1, ...(0, utils_1.mergeComponentProps)(inputBaseProps, inputProps), "data-hidden": "true" }), (0, jsx_runtime_1.jsx)("div", { className: selectBase_style_1.classes.arrow, "data-open": innerOpen.current, children: loading
|
|
99
|
+
? (0, jsx_runtime_1.jsx)(loadingIndicator_1.LoadingIndicator, {})
|
|
100
|
+
: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faChevronDown_1.faChevronDown }) })] }) }) }));
|
|
101
|
+
}
|
package/dist/cjs/components/{treeSelect/treeSelect.style.js → selectBase/selectBase.style.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.style = exports.classes = void 0;
|
|
4
|
-
const react_1 = require("@emotion/react");
|
|
5
4
|
const utils_1 = require("../../utils");
|
|
5
|
+
const react_1 = require("@emotion/react");
|
|
6
6
|
const tag_style_1 = require("../tag/tag.style");
|
|
7
|
-
exports.classes = (0, utils_1.defineInnerClasses)('
|
|
7
|
+
exports.classes = (0, utils_1.defineInnerClasses)('select-base', [
|
|
8
8
|
'contentWrap',
|
|
9
9
|
'placeholder',
|
|
10
10
|
'backfill',
|
|
@@ -19,7 +19,7 @@ exports.style = (0, utils_1.defineCss)(({ spacing, text, easing }) => (0, react_
|
|
|
19
19
|
.${exports.classes.contentWrap} {
|
|
20
20
|
display: flex;
|
|
21
21
|
align-items: center;
|
|
22
|
-
gap: ${spacing[
|
|
22
|
+
gap: ${spacing[2]}px;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
.${exports.classes.placeholder} {
|
|
@@ -43,8 +43,7 @@ export type ISelectionContext<O extends OptionType<V>, V extends Id = Id> = {
|
|
|
43
43
|
setOptions: Dispatch<SetStateAction<undefined | O[]>>;
|
|
44
44
|
optionsMap: Map<V, O>;
|
|
45
45
|
selectionStatus: Map<V, 1 | 2>;
|
|
46
|
-
toggleSelected(value: V
|
|
47
|
-
onToggle?(checked: boolean, value: V, option?: O): void;
|
|
46
|
+
toggleSelected(value: V): void;
|
|
48
47
|
};
|
|
49
48
|
export declare function useSelectionContext<O extends OptionType<V>, V extends Id = Id>(): ISelectionContext<O, V>;
|
|
50
49
|
export type SelectionContextProps<O extends OptionType<V>, V extends Id = Id> = SelectionContextBaseProps<O, V> & SelectableProps<V>;
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Dispatch, SetStateAction } from 'react';
|
|
2
2
|
import { ISelectionContext, OptionType, SelectionContextProps } from './selectionContext';
|
|
3
|
-
import { Id } from '../../types';
|
|
4
|
-
export declare function useSelection<O extends OptionType<V>, V extends Id = Id>(props: SelectionContextProps<O, V>): ISelectionContext<O, V>;
|
|
5
|
-
export
|
|
6
|
-
disabled?: boolean;
|
|
3
|
+
import { Id, SelectableProps } from '../../types';
|
|
4
|
+
export declare function useSelection<O extends OptionType<V>, V extends Id = Id>({ ...props }: SelectionContextProps<O, V>): ISelectionContext<O, V>;
|
|
5
|
+
export type UseFlatSelectionParams<V extends Id = Id> = Omit<SelectableProps<V>, 'multiple'> & {
|
|
7
6
|
multiple?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
8
|
clearable?: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
onChange?: (value: V) => void;
|
|
12
|
-
}): [V, (value: V) => void, Dispatch<SetStateAction<V>>];
|
|
9
|
+
};
|
|
10
|
+
export declare function useFlatSelection<V extends Id = Id>(params: UseFlatSelectionParams<V>): [V, (value: V) => void, Dispatch<SetStateAction<V>>];
|
|
@@ -5,15 +5,13 @@ exports.useFlatSelection = useFlatSelection;
|
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const selectionContext_1 = require("./selectionContext");
|
|
8
|
-
function useSelection(props) {
|
|
9
|
-
props
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
disabled: false
|
|
16
|
-
}, props);
|
|
8
|
+
function useSelection({ ...props }) {
|
|
9
|
+
props.primaryKey ??= 'id';
|
|
10
|
+
props.childrenKey ??= 'children';
|
|
11
|
+
props.relation ??= 'dependent';
|
|
12
|
+
props.integration ??= 'shallowest';
|
|
13
|
+
props.multiple ??= false;
|
|
14
|
+
props.disabled ??= false;
|
|
17
15
|
let [innerValue, setInnerValue] = (0, utils_1.useControlled)(props.defaultValue, props.value, props.onChange);
|
|
18
16
|
let [innerOptions, setInnerOptions] = (0, utils_1.useDerivedState)(props.options);
|
|
19
17
|
/**
|
|
@@ -203,8 +201,7 @@ function useSelection(props) {
|
|
|
203
201
|
setOptions: setInnerOptions,
|
|
204
202
|
optionsMap,
|
|
205
203
|
selectionStatus,
|
|
206
|
-
toggleSelected
|
|
207
|
-
onToggle: props.onToggle
|
|
204
|
+
toggleSelected
|
|
208
205
|
};
|
|
209
206
|
}
|
|
210
207
|
function useFlatSelection(params) {
|
|
@@ -14,8 +14,8 @@ exports.Tag = (0, react_1.memo)(({ variant = 'outlined', color = 'text.secondary
|
|
|
14
14
|
e.stopPropagation();
|
|
15
15
|
onClose?.(e);
|
|
16
16
|
};
|
|
17
|
-
return ((0, jsx_runtime_1.jsxs)("div", { ...props, css: (0, tag_style_1.useStyle)({ color
|
|
17
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ...props, css: (0, tag_style_1.useStyle)({ color }), className: (0, utils_1.clsx)(tag_style_1.classes.root, props.className), "data-variant": variant, "data-size": size, "data-shape": shape, "data-clickable": clickable, children: [!!prefix &&
|
|
18
18
|
(0, jsx_runtime_1.jsx)("div", { className: tag_style_1.classes.prefix, children: prefix }), (0, jsx_runtime_1.jsx)("div", { className: tag_style_1.classes.content, children: props.children }), !!suffix &&
|
|
19
19
|
(0, jsx_runtime_1.jsx)("div", { className: tag_style_1.classes.suffix, children: suffix }), closable &&
|
|
20
|
-
(0, jsx_runtime_1.jsx)(button_1.Button, { variant: "plain",
|
|
20
|
+
(0, jsx_runtime_1.jsx)(button_1.Button, { className: tag_style_1.classes.close, variant: "plain", color: color, onClick: closeHandler, children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faXmark_1.faXmark }) })] }));
|
|
21
21
|
});
|
|
@@ -12,7 +12,7 @@ export type SortInfo<V extends Id = Id> = {
|
|
|
12
12
|
destination: V;
|
|
13
13
|
placement: SortPlacement;
|
|
14
14
|
};
|
|
15
|
-
export interface
|
|
15
|
+
export interface TreeSharedProps<N extends NodeType<V>, V extends Id = Id> extends Omit<SelectionContextBaseProps<N, V>, 'options'> {
|
|
16
16
|
nodes?: N[];
|
|
17
17
|
/** 默认为`label` */
|
|
18
18
|
labelKey?: keyof N;
|
|
@@ -33,6 +33,8 @@ export interface TreeBaseProps<N extends NodeType<V>, V extends Id = Id> extends
|
|
|
33
33
|
/** 是否显示拖拽把手,默认为`true` */
|
|
34
34
|
showDragHandle?: boolean;
|
|
35
35
|
onSort?(info: SortInfo<V>): void;
|
|
36
|
+
}
|
|
37
|
+
export interface TreeBaseProps<N extends NodeType<V>, V extends Id = Id> extends TreeSharedProps<N, V>, Omit<DivProps, 'defaultValue' | 'onChange' | 'onToggle'> {
|
|
36
38
|
searchable?: boolean;
|
|
37
39
|
searchInputProps?: InputProps;
|
|
38
40
|
defaultSearchValue?: string;
|
|
@@ -18,7 +18,7 @@ const TreeContext = (0, react_2.createContext)({});
|
|
|
18
18
|
function useTreeContext() {
|
|
19
19
|
return (0, react_2.useContext)(TreeContext);
|
|
20
20
|
}
|
|
21
|
-
exports.Tree = (0, react_2.memo)(({ nodes, labelKey = 'label', searchTokenKey, showLine = true, indent = 24, renderExpandIcon, multiple, showCheckbox = !!multiple, readOnly, clickLabelToExpand, defaultExpanded, expanded, onExpandedChange, sortable = false, showDragHandle = true, onSort, searchable,
|
|
21
|
+
exports.Tree = (0, react_2.memo)(({ nodes, labelKey = 'label', searchTokenKey, showLine = true, indent = 24, renderExpandIcon, multiple, showCheckbox = !!multiple, readOnly, clickLabelToExpand = false, defaultExpanded, expanded, onExpandedChange, sortable = false, showDragHandle = true, onSort, searchable, defaultSearchValue = '', searchValue, onSearchChange, searchInputProps,
|
|
22
22
|
// 从SelectionContext继承来的属性
|
|
23
23
|
primaryKey = 'id', childrenKey = 'children', relation = 'dependent', integration = 'shallowest', clearable, disabled, defaultValue, value, onChange, onToggle, ...props }) => {
|
|
24
24
|
/**
|
|
@@ -58,7 +58,7 @@ primaryKey = 'id', childrenKey = 'children', relation = 'dependent', integration
|
|
|
58
58
|
setInnerSearchValue(e.target.value);
|
|
59
59
|
} }), (0, jsx_runtime_1.jsx)(selectionContext_1.SelectionContext, { ...{
|
|
60
60
|
options: actualTreeNodes, primaryKey, childrenKey, relation, integration,
|
|
61
|
-
multiple, defaultValue, value, onChange,
|
|
61
|
+
disabled, multiple, defaultValue, value, onChange, onToggle
|
|
62
62
|
}, children: (0, jsx_runtime_1.jsx)(TreeContext, { value: (0, react_2.useMemo)(() => ({
|
|
63
63
|
expandedSet, toggleExpanded, indent, renderExpandIcon, clickLabelToExpand,
|
|
64
64
|
showCheckbox, readOnly, disabled
|