@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.
Files changed (51) hide show
  1. package/dist/cjs/components/app/app.js +8 -4
  2. package/dist/cjs/components/cascade/cascade.style.d.ts +1 -1
  3. package/dist/cjs/components/dataGrid/dataGridRows.js +2 -4
  4. package/dist/cjs/components/inputBase/inputBase.js +1 -1
  5. package/dist/cjs/components/optionsBase/optionsBase.js +24 -23
  6. package/dist/cjs/components/select/select.d.ts +7 -25
  7. package/dist/cjs/components/select/select.js +31 -107
  8. package/dist/cjs/components/selectBase/index.d.ts +1 -0
  9. package/dist/cjs/components/selectBase/index.js +4 -0
  10. package/dist/cjs/components/selectBase/selectBase.d.ts +41 -0
  11. package/dist/cjs/components/selectBase/selectBase.js +101 -0
  12. package/dist/cjs/components/{treeSelect/treeSelect.style.js → selectBase/selectBase.style.js} +3 -3
  13. package/dist/cjs/components/selectionContext/selectionContext.d.ts +1 -2
  14. package/dist/cjs/components/selectionContext/selectionHook.d.ts +6 -8
  15. package/dist/cjs/components/selectionContext/selectionHook.js +8 -11
  16. package/dist/cjs/components/tag/tag.js +2 -2
  17. package/dist/cjs/components/tree/tree.d.ts +3 -1
  18. package/dist/cjs/components/tree/tree.js +2 -2
  19. package/dist/cjs/components/tree/treeNode.js +1 -1
  20. package/dist/cjs/components/treeSelect/treeSelect.d.ts +8 -24
  21. package/dist/cjs/components/treeSelect/treeSelect.js +53 -51
  22. package/dist/esm/components/app/app.js +8 -4
  23. package/dist/esm/components/cascade/cascade.style.d.ts +1 -1
  24. package/dist/esm/components/dataGrid/dataGridRows.js +2 -4
  25. package/dist/esm/components/inputBase/inputBase.js +1 -1
  26. package/dist/esm/components/optionsBase/optionsBase.js +24 -23
  27. package/dist/esm/components/select/select.d.ts +7 -25
  28. package/dist/esm/components/select/select.js +33 -109
  29. package/dist/esm/components/selectBase/index.d.ts +1 -0
  30. package/dist/esm/components/selectBase/index.js +1 -0
  31. package/dist/esm/components/selectBase/selectBase.d.ts +41 -0
  32. package/dist/esm/components/selectBase/selectBase.js +98 -0
  33. package/dist/esm/components/{select/select.style.js → selectBase/selectBase.style.js} +13 -13
  34. package/dist/esm/components/selectionContext/selectionContext.d.ts +1 -2
  35. package/dist/esm/components/selectionContext/selectionHook.d.ts +6 -8
  36. package/dist/esm/components/selectionContext/selectionHook.js +8 -11
  37. package/dist/esm/components/tag/tag.js +2 -2
  38. package/dist/esm/components/tree/tree.d.ts +3 -1
  39. package/dist/esm/components/tree/tree.js +2 -2
  40. package/dist/esm/components/tree/treeNode.js +1 -1
  41. package/dist/esm/components/treeSelect/treeSelect.d.ts +8 -24
  42. package/dist/esm/components/treeSelect/treeSelect.js +54 -52
  43. package/documentation/dist/assets/{index-kzMR4-bu.js → index-DyrGMYuH.js} +879 -926
  44. package/documentation/dist/index.html +1 -1
  45. package/package.json +1 -1
  46. package/dist/cjs/components/select/select.style.js +0 -61
  47. package/dist/cjs/components/treeSelect/treeSelect.style.d.ts +0 -10
  48. package/dist/esm/components/treeSelect/treeSelect.style.d.ts +0 -10
  49. package/dist/esm/components/treeSelect/treeSelect.style.js +0 -58
  50. package/dist/cjs/components/{select/select.style.d.ts → selectBase/selectBase.style.d.ts} +1 -1
  51. 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: exports.App.dialog ||= new appDialog_1.AppDialogMethods(),
32
- message: exports.App.message ||= new appMessage_1.AppMessageMethods(),
33
- notification: exports.App.notification ||= new appNotification_1.AppNotificationMethods(),
34
- actionSheet: exports.App.actionSheet ||= new appActionSheet_1.AppActionSheetMethods()
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,
@@ -1,9 +1,9 @@
1
1
  export declare const classes: {
2
2
  placeholder: string;
3
3
  contentWrap: string;
4
- arrow: string;
5
4
  backfill: string;
6
5
  backfillWrap: string;
6
+ arrow: string;
7
7
  searchInput: string;
8
8
  panelContainer: string;
9
9
  panel: string;
@@ -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, row);
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
- ref: params.scrollHere || params.selected ? selectedItemRef : void 0,
79
- showCheckbox,
80
- selected: params.selected,
81
- focused: verticalIndex.current === params.index,
82
- label: typeof params.label === 'string' && searchValue
83
- ? (0, jsx_runtime_1.jsx)(highlight_1.Highlight, { keywords: searchValue?.split(' '), children: params.label })
84
- : params.label,
85
- onClick: e => {
86
- e.stopPropagation();
87
- params.opt?.onClick?.(e);
88
- syncOnToggleSelected.current?.(params.value, e);
89
- },
90
- onPointerEnter: e => {
91
- params.opt?.onPointerEnter?.(e);
92
- setVerticalIndex(-1);
93
- },
94
- children: null
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, { value: value, ...(0, utils_1.mergeComponentProps)(opt, makeProps({
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
- })) }, opt.key ?? value ?? index));
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
- opt: c.props,
117
+ option: c.props,
117
118
  label,
118
119
  value: value,
119
120
  index,
@@ -1,31 +1,13 @@
1
- import { ReactElement, ReactNode, Ref, ComponentProps } from 'react';
2
- import { InputBaseProps } from '../inputBase';
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 { InputProps } from '../input';
7
- import { Id, SelectableMultipleProps, SelectableSingleProps } from '../../types';
8
- export interface SelectBaseProps<O extends MenuOptionType> extends OptionsBaseSharedProps<O>, Omit<InputBaseProps<'input'>, 'children' | 'defaultValue' | 'value' | 'onChange'> {
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 SelectBaseProps<O>, SelectableSingleProps<V> {
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 SelectBaseProps<O>, SelectableMultipleProps<V> {
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 inputBase_1 = require("../inputBase");
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 input_1 = require("../input");
14
- const loadingIndicator_1 = require("../loadingIndicator");
8
+ const menuItem_1 = require("../menuItem");
15
9
  const selectionContext_1 = require("../selectionContext");
16
- const icon_1 = require("../icon");
17
- const faChevronDown_1 = require("@fortawesome/free-solid-svg-icons/faChevronDown");
18
- const faMagnifyingGlass_1 = require("@fortawesome/free-solid-svg-icons/faMagnifyingGlass");
19
- const popper_style_1 = require("../popper/popper.style");
20
- exports.Select = (0, react_1.memo)(({ inputProps, popperProps, popperRef, defaultOpen = false, open, onOpenChange, sizeAdaptable = true, children, multiple, defaultValue, value, onChange, renderBackfill, searchable, defaultSearchValue = '', searchValue, onSearchChange, searchInputProps,
21
- // 从OptionsBaseSharedProps继承的属性
22
- showCheckbox = !!multiple, loading, options, labelKey = 'label', primaryKey = 'value', searchTokenKey = 'searchToken', filterPredicate, ...props }) => {
23
- const [innerOpen, _setInnerOpen] = (0, utils_1.useControlled)(defaultOpen, open, onOpenChange);
24
- const setInnerOpen = (open) => {
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 renderBackfillFn = () => {
74
- if (renderBackfill) {
75
- return renderBackfill(innerValue);
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)(popper_1.Popper, { ...(0, utils_1.mergeComponentProps)({
83
- css: popper_style_1.popperStyle,
84
- open: innerOpen.current,
85
- placement: 'bottom',
86
- variant: 'collapse',
87
- trigger: ['click', 'enter'],
88
- disabled: props.disabled || props.readOnly,
89
- sizeAdaptable: sizeAdaptable,
90
- content: ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [searchable &&
91
- (0, jsx_runtime_1.jsx)(input_1.Input, { ...(0, utils_1.mergeComponentProps)({
92
- inputProps: (0, utils_1.mergeComponentProps)(searchInputProps?.inputProps, { ref: searchInputRef }),
93
- prefix: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faMagnifyingGlass_1.faMagnifyingGlass }),
94
- placeholder: '搜索',
95
- value: innerSearchValue.current
96
- }, searchInputProps, {
97
- onChange: e => setInnerSearchValue?.(e.target.value),
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,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./selectBase"), exports);
@@ -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
+ }
@@ -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)('tree-select', [
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[1]}px;
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, option?: O): void;
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 declare function useFlatSelection<V extends Id | Id[]>(params: {
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
- defaultValue?: V;
10
- value?: V;
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 = Object.assign({
10
- primaryKey: 'id',
11
- childrenKey: 'children',
12
- relation: 'dependent',
13
- integration: 'shallowest',
14
- multiple: false,
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: color || 'text.secondary' }), 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 &&
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", className: tag_style_1.classes.close, onClick: closeHandler, children: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: faXmark_1.faXmark }) })] }));
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 TreeBaseProps<N extends NodeType<V>, V extends Id = Id> extends Omit<SelectionContextBaseProps<N, V>, 'options'>, Omit<DivProps, 'defaultValue' | 'onChange' | 'onToggle'> {
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, searchInputProps, defaultSearchValue, searchValue, onSearchChange,
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, disabled
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