@canlooks/can-ui 0.0.139 → 0.0.141

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.
@@ -58,9 +58,14 @@ exports.Curd = (0, react_1.memo)((props) => {
58
58
  * -------------------------------------------------------------
59
59
  * 筛选部分
60
60
  */
61
+ const inlineFilterRef = (0, react_1.useRef)(null);
61
62
  const innerFilterRef = (0, react_1.useRef)(null);
62
- const filterHandler = (value) => {
63
- onFilter?.(value);
63
+ const getFilterValue = () => ({
64
+ ...inlineFilterRef.current.getFormValue(),
65
+ ...innerFilterRef.current.getFormValue()
66
+ });
67
+ const filterHandler = () => {
68
+ onFilter?.(getFilterValue());
64
69
  innerLoadRows().then();
65
70
  };
66
71
  const renderFilterableFn = () => {
@@ -139,7 +144,7 @@ exports.Curd = (0, react_1.memo)((props) => {
139
144
  page: innerPage.current,
140
145
  pageSize: innerPageSize.current
141
146
  }
142
- : void 0, innerFilterRef.current.getFormValue(), innerOrderColumn.current
147
+ : void 0, getFilterValue(), innerOrderColumn.current
143
148
  ? {
144
149
  field: innerOrderColumn.current,
145
150
  type: innerOrderType.current
@@ -207,7 +212,7 @@ exports.Curd = (0, react_1.memo)((props) => {
207
212
  }, filterProps, {
208
213
  ref: innerFilterRef,
209
214
  ...filterableProps?.showButton === false
210
- ? { onChange: (field, value, formValue) => filterHandler(formValue) }
215
+ ? { onChange: filterHandler }
211
216
  : { onFinish: filterHandler }
212
217
  }), children: renderFilterableFn() }), (creatable || toolbarLeft || toolbarRight || reloadable || resizable || columnConfigurable) &&
213
218
  (0, jsx_runtime_1.jsxs)("div", { className: curd_style_1.classes.toolbar, children: [(0, jsx_runtime_1.jsxs)("div", { className: curd_style_1.classes.toolbarLeft, children: [creatable &&
@@ -218,7 +223,7 @@ exports.Curd = (0, react_1.memo)((props) => {
218
223
  (0, jsx_runtime_1.jsx)(curdColumnConfig_1.CurdColumnConfig, { columns: orderedColumns, innerVisible: innerVisible.current, setInnerVisible: setInnerVisible, setInnerOrder: setInnerOrder })] })] }), (0, jsx_runtime_1.jsx)("div", { className: curd_style_1.classes.card, children: (0, jsx_runtime_1.jsx)(dataGrid_1.DataGrid, { ...dataGridProps, columns: actualColumns, tableProps: {
219
224
  ...props.tableProps,
220
225
  ...resizable && { size: innerSize.current }
221
- }, loading: innerLoading.current, rows: innerRows.current, paginatable: !loadRows && props.paginatable, renderPagination: loadRows && props.paginatable !== false
226
+ }, loading: innerLoading.current, rows: innerRows.current, filterProps: { ref: inlineFilterRef }, onFilter: filterHandler, paginatable: !loadRows && props.paginatable, renderPagination: loadRows && props.paginatable !== false
222
227
  ? () => (0, jsx_runtime_1.jsx)(pagination_1.Pagination, { ...props.paginationProps, total: innerTotal.current, page: innerPage.current, onPageChange: setInnerPage, pageSize: innerPageSize.current, onPageSizeChange: setInnerPageSize })
223
228
  : props.renderPagination, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler }) }), (creatable || updatable) &&
224
229
  (0, jsx_runtime_1.jsx)(curdDialog_1.CurdDialog, { ...dialogProps, ref: curdDialogRef, onFinish: finishHandler, curdProps: props })] }));
@@ -8,6 +8,7 @@ import { RadioProps } from '../radio';
8
8
  import { FieldPath } from '../../utils';
9
9
  import { FormProps, FormValue } from '../form';
10
10
  import { FilterControlProps, FilterOptionsProps } from './filterBubbleContent';
11
+ import { BubbleProps } from '../bubble';
11
12
  export type RowType = Obj;
12
13
  export interface ColumnType<R extends RowType = RowType> extends Omit<ComponentProps<'td'>, 'key' | 'ref' | 'title' | 'children'>, Omit<ComponentProps<'th'>, 'key' | 'ref' | 'title' | 'children'> {
13
14
  title?: ReactNode;
@@ -73,6 +74,7 @@ export interface DataGridBaseProps<R extends RowType = RowType> extends DataGrid
73
74
  rows?: R[];
74
75
  filterProps?: FormProps;
75
76
  initialFilterValue?: FormValue;
77
+ filterBubbleProps?: BubbleProps;
76
78
  onFilter?(filterValue: FormValue): void;
77
79
  onFilterClick?(column: Id, e: React.MouseEvent<HTMLButtonElement>): void;
78
80
  /** 若需要本地筛选,必须指定该方法 */
@@ -19,7 +19,7 @@ const DataGridContext = (0, react_1.createContext)({});
19
19
  function useDataGridContext() {
20
20
  return (0, react_1.useContext)(DataGridContext);
21
21
  }
22
- exports.DataGrid = (0, react_1.memo)(({ slots, slotProps, columns, rows, rowProps, primaryKey = 'id', childrenKey = null, filterProps, initialFilterValue, onFilter, onFilterClick, filterPredicate, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded, expanded, onExpandedChange, paginatable = true, paginationProps, renderPagination, loading, emptyPlaceholder, columnResizable = false, size, bordered, striped, tableProps, multiple, defaultValue, value, onChange, ...props }) => {
22
+ exports.DataGrid = (0, react_1.memo)(({ slots, slotProps, columns, rows, rowProps, primaryKey = 'id', childrenKey = null, filterProps, initialFilterValue, filterBubbleProps, onFilter, onFilterClick, filterPredicate, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded, expanded, onExpandedChange, paginatable = true, paginationProps, renderPagination, loading, emptyPlaceholder, columnResizable = false, size, bordered, striped, tableProps, multiple, defaultValue, value, onChange, ...props }) => {
23
23
  /**
24
24
  * ---------------------------------------------------------------
25
25
  * 选择行
@@ -131,12 +131,12 @@ exports.DataGrid = (0, react_1.memo)(({ slots, slotProps, columns, rows, rowProp
131
131
  return orderedRows?.slice((page - 1) * pageSize, page * pageSize);
132
132
  }, [orderedRows, _paginationProps.page, _paginationProps.pageSize, paginatable]);
133
133
  return ((0, jsx_runtime_1.jsxs)(loading_1.Loading, { fill: false, ...props, css: dataGrid_style_1.style, className: (0, utils_1.clsx)(dataGrid_style_1.classes.root, props.className), open: loading, "data-column-resizable": columnResizable, children: [(0, jsx_runtime_1.jsx)(form_1.Form, { ...(0, utils_1.mergeComponentProps)({
134
+ className: dataGrid_style_1.classes.filterForm,
134
135
  variant: 'plain',
135
136
  initialValue: innerFilterValue
136
137
  }, filterProps, {
137
- className: dataGrid_style_1.classes.filterForm,
138
138
  onFinish: filterHandler
139
- }), children: (0, jsx_runtime_1.jsx)(columnResize_1.ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => (0, jsx_runtime_1.jsxs)(table_1.TableContainer, { ref: scrollerRef, className: dataGrid_style_1.classes.container, children: [(0, jsx_runtime_1.jsx)(table_1.Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: (0, utils_1.cloneRef)(tableProps?.ref, tableRef), children: (0, jsx_runtime_1.jsxs)(selectionContext_1.SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(dataGridHead_1.DataGridHead, { rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, onFilterClick: onFilterClick }), (0, jsx_runtime_1.jsx)("tbody", { children: (0, jsx_runtime_1.jsx)(DataGridContext, { value: (0, react_1.useMemo)(() => ({
139
+ }), children: (0, jsx_runtime_1.jsx)(columnResize_1.ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => (0, jsx_runtime_1.jsxs)(table_1.TableContainer, { ref: scrollerRef, className: dataGrid_style_1.classes.container, children: [(0, jsx_runtime_1.jsx)(table_1.Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: (0, utils_1.cloneRef)(tableProps?.ref, tableRef), children: (0, jsx_runtime_1.jsxs)(selectionContext_1.SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, children: [(0, jsx_runtime_1.jsx)(dataGridHead_1.DataGridHead, { rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, filterBubbleProps: filterBubbleProps, onFilterClick: onFilterClick }), (0, jsx_runtime_1.jsx)("tbody", { children: (0, jsx_runtime_1.jsx)(DataGridContext, { value: (0, react_1.useMemo)(() => ({
140
140
  slots, slotProps,
141
141
  rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon,
142
142
  expandedSet, flattedColumns, toggleExpanded
@@ -6,6 +6,7 @@ interface DataGridHeadProps<R extends RowType, V extends Id = Id> extends Requir
6
6
  orderColumn: Id | undefined;
7
7
  flattedColumns: (symbol | ColumnType<R>)[] | undefined;
8
8
  completedColumns: (symbol | ColumnType<R>)[] | undefined;
9
+ filterBubbleProps: DataGridProps<R, V>['filterBubbleProps'];
9
10
  onFilterClick: DataGridProps<R, V>['onFilterClick'];
10
11
  }
11
12
  export declare const DataGridHead: <R extends RowType, V extends Id = Id>(props: DataGridHeadProps<R, V>) => ReactElement;
@@ -18,7 +18,7 @@ const bubble_1 = require("../bubble");
18
18
  const filterBubbleContent_1 = require("./filterBubbleContent");
19
19
  const form_1 = require("../form");
20
20
  const utils_1 = require("../../utils");
21
- exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, onFilterClick }) => {
21
+ exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
22
22
  const { multiple, setValue, selectionStatus } = (0, selectionContext_1.useSelectionContext)();
23
23
  const allSelectionStatus = (0, react_2.useMemo)(() => {
24
24
  if (multiple && allowSelectAll) {
@@ -103,7 +103,14 @@ exports.DataGridHead = (0, react_2.memo)(({ allowSelectAll, columnResizable, fla
103
103
  : (0, jsx_runtime_1.jsx)("div", { className: dataGrid_style_1.classes.title, children: title }), filter &&
104
104
  (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { title: "\u7B5B\u9009", placement: "top", clickToClose: true, children: filter === true
105
105
  ? filterButton
106
- : (0, jsx_runtime_1.jsx)(bubble_1.Bubble, { style: { maxWidth: 360 }, trigger: "click", placement: "bottomRight", autoClose: false, content: (0, jsx_runtime_1.jsx)(filterBubbleContent_1.FilterBubbleContent, { columnKey: _key, columnFilterProps: filter }), onClick: e => e.stopPropagation(), children: filterButton }) })] })
106
+ : (0, jsx_runtime_1.jsx)(bubble_1.Bubble, { ...(0, utils_1.mergeComponentProps)({
107
+ style: { maxWidth: 360 },
108
+ trigger: 'click',
109
+ placement: 'bottomRight',
110
+ autoClose: false,
111
+ content: ((0, jsx_runtime_1.jsx)(filterBubbleContent_1.FilterBubbleContent, { columnKey: _key, columnFilterProps: filter })),
112
+ onClick: e => e.stopPropagation()
113
+ }, filterBubbleProps), children: filterButton }) })] })
107
114
  : title)
108
115
  ];
109
116
  }) }, i));
@@ -8,6 +8,8 @@ type FilterSharedProps = {
8
8
  export interface FilterOptionsProps extends FilterSharedProps, OptionsBaseProps<MenuOptionType> {
9
9
  /** 默认为`true` */
10
10
  multiple?: boolean;
11
+ /** 默认为`false` */
12
+ searchable?: boolean;
11
13
  }
12
14
  export interface FilterControlProps extends FilterSharedProps {
13
15
  control: FormItemChildren;
@@ -9,33 +9,43 @@ const button_1 = require("../button");
9
9
  const popper_1 = require("../popper");
10
10
  const react_1 = require("react");
11
11
  const form_1 = require("../form");
12
+ const filterBubbleContent_style_1 = require("./filterBubbleContent.style");
13
+ const input_1 = require("../input");
14
+ const icon_1 = require("../icon");
15
+ const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
16
+ const utils_1 = require("../../utils");
12
17
  exports.FilterBubbleContent = (0, react_1.memo)(({ columnKey, columnFilterProps }) => {
13
18
  const { formRef } = (0, form_1.useFormContext)();
14
- /**
15
- * ------------------------------------------------------------------------------------
16
- * 弹框关闭时触发筛选
17
- */
18
19
  const { open, setOpen } = (0, popper_1.usePopperContext)();
19
20
  (0, react_1.useEffect)(() => {
20
- !open && formRef.current.submit().then();
21
+ if (!open && !('control' in columnFilterProps) && columnFilterProps.multiple) {
22
+ // 多选模式下,关闭弹框触发筛选
23
+ formRef.current.submit().then();
24
+ }
21
25
  }, [open]);
22
26
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(form_1.FormItem, { field: columnKey, children: 'control' in columnFilterProps
23
27
  ? columnFilterProps.control
24
- : (0, jsx_runtime_1.jsx)(FilterOptions, { ...columnFilterProps }) }), columnFilterProps.showButton !== false
25
- ? (0, jsx_runtime_1.jsx)(flex_1.Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: (0, jsx_runtime_1.jsx)(button_1.Button, { variant: "text", onClick: () => {
28
+ : (0, jsx_runtime_1.jsx)(FilterOptions, { ...columnFilterProps, onChange: value => {
29
+ columnFilterProps.onChange?.(value);
30
+ !columnFilterProps.multiple && setOpen(false);
31
+ } }) }), columnFilterProps.showButton !== false &&
32
+ (0, jsx_runtime_1.jsx)(flex_1.Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: (0, jsx_runtime_1.jsx)(button_1.Button, { variant: "text", onClick: () => {
26
33
  formRef.current.setFieldValue(columnKey, null);
27
34
  setOpen(false);
28
- }, children: "\u91CD\u7F6E" }) })
29
- : (0, jsx_runtime_1.jsx)(TriggerFilterOnChange, {})] }));
35
+ }, children: "\u91CD\u7F6E" }) }), !('control' in columnFilterProps) && !columnFilterProps.multiple &&
36
+ // 单选模式,变化即触发筛选
37
+ (0, jsx_runtime_1.jsx)(TriggerFilterOnChange, {})] }));
30
38
  });
31
- const FilterOptions = (0, react_1.memo)(({ multiple = true, showButton = true, value, onChange, ...props }) => {
39
+ const FilterOptions = (0, react_1.memo)(({ multiple = true, showButton = true, searchable = false, value, onChange, ...props }) => {
32
40
  const [selectedValue, toggleSelect] = (0, selectionContext_1.useFlatSelection)({ multiple, value, onChange });
33
- return ((0, jsx_runtime_1.jsx)(optionsBase_1.OptionsBase, { showCheckbox: multiple, ...props, selectedValue: selectedValue, onToggleSelected: toggleSelect }));
41
+ const [searchValue, setSearchValue] = (0, react_1.useState)('');
42
+ const deferredSearchValue = (0, react_1.useDeferredValue)(searchValue);
43
+ return ((0, jsx_runtime_1.jsxs)("div", { css: filterBubbleContent_style_1.style, children: [(0, jsx_runtime_1.jsx)(input_1.Input, { prefix: (0, jsx_runtime_1.jsx)(icon_1.Icon, { icon: free_solid_svg_icons_1.faSearch }), placeholder: "\u641C\u7D22", value: searchValue, onChange: e => setSearchValue(e.target.value) }), (0, jsx_runtime_1.jsx)(optionsBase_1.OptionsBase, { showCheckbox: multiple, ...props, searchValue: deferredSearchValue, selectedValue: selectedValue, onToggleSelected: toggleSelect })] }));
34
44
  });
35
45
  const TriggerFilterOnChange = (0, react_1.memo)(() => {
36
46
  const { formRef } = (0, form_1.useFormContext)();
37
47
  const { formValue } = (0, form_1.useFormValueContext)();
38
- (0, react_1.useEffect)(() => {
48
+ (0, utils_1.useUpdateEffect)(() => {
39
49
  formRef.current.submit().then();
40
50
  }, [formValue]);
41
51
  return null;
@@ -0,0 +1 @@
1
+ export declare const style: import("@emotion/react").SerializedStyles;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.style = void 0;
4
+ const react_1 = require("@emotion/react");
5
+ exports.style = (0, react_1.css) `
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 4px
9
+ `;
@@ -55,9 +55,14 @@ export const Curd = memo((props) => {
55
55
  * -------------------------------------------------------------
56
56
  * 筛选部分
57
57
  */
58
+ const inlineFilterRef = useRef(null);
58
59
  const innerFilterRef = useRef(null);
59
- const filterHandler = (value) => {
60
- onFilter?.(value);
60
+ const getFilterValue = () => ({
61
+ ...inlineFilterRef.current.getFormValue(),
62
+ ...innerFilterRef.current.getFormValue()
63
+ });
64
+ const filterHandler = () => {
65
+ onFilter?.(getFilterValue());
61
66
  innerLoadRows().then();
62
67
  };
63
68
  const renderFilterableFn = () => {
@@ -136,7 +141,7 @@ export const Curd = memo((props) => {
136
141
  page: innerPage.current,
137
142
  pageSize: innerPageSize.current
138
143
  }
139
- : void 0, innerFilterRef.current.getFormValue(), innerOrderColumn.current
144
+ : void 0, getFilterValue(), innerOrderColumn.current
140
145
  ? {
141
146
  field: innerOrderColumn.current,
142
147
  type: innerOrderType.current
@@ -204,7 +209,7 @@ export const Curd = memo((props) => {
204
209
  }, filterProps, {
205
210
  ref: innerFilterRef,
206
211
  ...filterableProps?.showButton === false
207
- ? { onChange: (field, value, formValue) => filterHandler(formValue) }
212
+ ? { onChange: filterHandler }
208
213
  : { onFinish: filterHandler }
209
214
  }), children: renderFilterableFn() }), (creatable || toolbarLeft || toolbarRight || reloadable || resizable || columnConfigurable) &&
210
215
  _jsxs("div", { className: classes.toolbar, children: [_jsxs("div", { className: classes.toolbarLeft, children: [creatable &&
@@ -215,7 +220,7 @@ export const Curd = memo((props) => {
215
220
  _jsx(CurdColumnConfig, { columns: orderedColumns, innerVisible: innerVisible.current, setInnerVisible: setInnerVisible, setInnerOrder: setInnerOrder })] })] }), _jsx("div", { className: classes.card, children: _jsx(DataGrid, { ...dataGridProps, columns: actualColumns, tableProps: {
216
221
  ...props.tableProps,
217
222
  ...resizable && { size: innerSize.current }
218
- }, loading: innerLoading.current, rows: innerRows.current, paginatable: !loadRows && props.paginatable, renderPagination: loadRows && props.paginatable !== false
223
+ }, loading: innerLoading.current, rows: innerRows.current, filterProps: { ref: inlineFilterRef }, onFilter: filterHandler, paginatable: !loadRows && props.paginatable, renderPagination: loadRows && props.paginatable !== false
219
224
  ? () => _jsx(Pagination, { ...props.paginationProps, total: innerTotal.current, page: innerPage.current, onPageChange: setInnerPage, pageSize: innerPageSize.current, onPageSizeChange: setInnerPageSize })
220
225
  : props.renderPagination, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler }) }), (creatable || updatable) &&
221
226
  _jsx(CurdDialog, { ...dialogProps, ref: curdDialogRef, onFinish: finishHandler, curdProps: props })] }));
@@ -8,6 +8,7 @@ import { RadioProps } from '../radio';
8
8
  import { FieldPath } from '../../utils';
9
9
  import { FormProps, FormValue } from '../form';
10
10
  import { FilterControlProps, FilterOptionsProps } from './filterBubbleContent';
11
+ import { BubbleProps } from '../bubble';
11
12
  export type RowType = Obj;
12
13
  export interface ColumnType<R extends RowType = RowType> extends Omit<ComponentProps<'td'>, 'key' | 'ref' | 'title' | 'children'>, Omit<ComponentProps<'th'>, 'key' | 'ref' | 'title' | 'children'> {
13
14
  title?: ReactNode;
@@ -73,6 +74,7 @@ export interface DataGridBaseProps<R extends RowType = RowType> extends DataGrid
73
74
  rows?: R[];
74
75
  filterProps?: FormProps;
75
76
  initialFilterValue?: FormValue;
77
+ filterBubbleProps?: BubbleProps;
76
78
  onFilter?(filterValue: FormValue): void;
77
79
  onFilterClick?(column: Id, e: React.MouseEvent<HTMLButtonElement>): void;
78
80
  /** 若需要本地筛选,必须指定该方法 */
@@ -15,7 +15,7 @@ const DataGridContext = createContext({});
15
15
  export function useDataGridContext() {
16
16
  return useContext(DataGridContext);
17
17
  }
18
- export const DataGrid = memo(({ slots, slotProps, columns, rows, rowProps, primaryKey = 'id', childrenKey = null, filterProps, initialFilterValue, onFilter, onFilterClick, filterPredicate, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded, expanded, onExpandedChange, paginatable = true, paginationProps, renderPagination, loading, emptyPlaceholder, columnResizable = false, size, bordered, striped, tableProps, multiple, defaultValue, value, onChange, ...props }) => {
18
+ export const DataGrid = memo(({ slots, slotProps, columns, rows, rowProps, primaryKey = 'id', childrenKey = null, filterProps, initialFilterValue, filterBubbleProps, onFilter, onFilterClick, filterPredicate, defaultOrderColumn, orderColumn, defaultOrderType = 'descend', orderType, onOrderChange, selectable, relation = 'dependent', integration = 'shallowest', allowSelectAll = true, clickRowToSelect = true, selectorProps, indent = 24, renderExpandIcon, defaultExpanded, expanded, onExpandedChange, paginatable = true, paginationProps, renderPagination, loading, emptyPlaceholder, columnResizable = false, size, bordered, striped, tableProps, multiple, defaultValue, value, onChange, ...props }) => {
19
19
  /**
20
20
  * ---------------------------------------------------------------
21
21
  * 选择行
@@ -127,12 +127,12 @@ export const DataGrid = memo(({ slots, slotProps, columns, rows, rowProps, prima
127
127
  return orderedRows?.slice((page - 1) * pageSize, page * pageSize);
128
128
  }, [orderedRows, _paginationProps.page, _paginationProps.pageSize, paginatable]);
129
129
  return (_jsxs(Loading, { fill: false, ...props, css: style, className: clsx(classes.root, props.className), open: loading, "data-column-resizable": columnResizable, children: [_jsx(Form, { ...mergeComponentProps({
130
+ className: classes.filterForm,
130
131
  variant: 'plain',
131
132
  initialValue: innerFilterValue
132
133
  }, filterProps, {
133
- className: classes.filterForm,
134
134
  onFinish: filterHandler
135
- }), children: _jsx(ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => _jsxs(TableContainer, { ref: scrollerRef, className: classes.container, children: [_jsx(Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: cloneRef(tableProps?.ref, tableRef), children: _jsxs(SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, children: [_jsx(DataGridHead, { rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, onFilterClick: onFilterClick }), _jsx("tbody", { children: _jsx(DataGridContext, { value: useMemo(() => ({
135
+ }), children: _jsx(ColumnResizeContext, { columnResizable: columnResizable, children: ({ scrollerRef, tableRef }) => _jsxs(TableContainer, { ref: scrollerRef, className: classes.container, children: [_jsx(Table, { size: size, bordered: bordered, striped: striped, ...tableProps, ref: cloneRef(tableProps?.ref, tableRef), children: _jsxs(SelectionContext, { options: rows, primaryKey: primaryKey, childrenKey: childrenKey !== null ? childrenKey : void 0, relation: relation, integration: integration, disabled: !selectable, multiple: multiple, defaultValue: defaultValue, value: value, onChange: onChange, children: [_jsx(DataGridHead, { rows: rows, flattedColumns: flattedColumns, completedColumns: completedColumns, primaryKey: primaryKey, allowSelectAll: allowSelectAll, columnResizable: columnResizable, orderColumn: innerOrderColumn.current, orderType: innerOrderType.current, onOrderChange: orderChangeHandler, filterBubbleProps: filterBubbleProps, onFilterClick: onFilterClick }), _jsx("tbody", { children: _jsx(DataGridContext, { value: useMemo(() => ({
136
136
  slots, slotProps,
137
137
  rowProps, primaryKey, childrenKey, clickRowToSelect, indent, renderExpandIcon,
138
138
  expandedSet, flattedColumns, toggleExpanded
@@ -6,6 +6,7 @@ interface DataGridHeadProps<R extends RowType, V extends Id = Id> extends Requir
6
6
  orderColumn: Id | undefined;
7
7
  flattedColumns: (symbol | ColumnType<R>)[] | undefined;
8
8
  completedColumns: (symbol | ColumnType<R>)[] | undefined;
9
+ filterBubbleProps: DataGridProps<R, V>['filterBubbleProps'];
9
10
  onFilterClick: DataGridProps<R, V>['onFilterClick'];
10
11
  }
11
12
  export declare const DataGridHead: <R extends RowType, V extends Id = Id>(props: DataGridHeadProps<R, V>) => ReactElement;
@@ -14,8 +14,8 @@ import { faFilter } from '@fortawesome/free-solid-svg-icons/faFilter';
14
14
  import { Bubble } from '../bubble';
15
15
  import { FilterBubbleContent } from './filterBubbleContent';
16
16
  import { useFormValueContext } from '../form';
17
- import { isUnset } from '../../utils';
18
- export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, onFilterClick }) => {
17
+ import { isUnset, mergeComponentProps } from '../../utils';
18
+ export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColumns, completedColumns, rows, primaryKey, orderColumn, orderType, onOrderChange, filterBubbleProps, onFilterClick }) => {
19
19
  const { multiple, setValue, selectionStatus } = useSelectionContext();
20
20
  const allSelectionStatus = useMemo(() => {
21
21
  if (multiple && allowSelectAll) {
@@ -100,7 +100,14 @@ export const DataGridHead = memo(({ allowSelectAll, columnResizable, flattedColu
100
100
  : _jsx("div", { className: classes.title, children: title }), filter &&
101
101
  _jsx(Tooltip, { title: "\u7B5B\u9009", placement: "top", clickToClose: true, children: filter === true
102
102
  ? filterButton
103
- : _jsx(Bubble, { style: { maxWidth: 360 }, trigger: "click", placement: "bottomRight", autoClose: false, content: _jsx(FilterBubbleContent, { columnKey: _key, columnFilterProps: filter }), onClick: e => e.stopPropagation(), children: filterButton }) })] })
103
+ : _jsx(Bubble, { ...mergeComponentProps({
104
+ style: { maxWidth: 360 },
105
+ trigger: 'click',
106
+ placement: 'bottomRight',
107
+ autoClose: false,
108
+ content: (_jsx(FilterBubbleContent, { columnKey: _key, columnFilterProps: filter })),
109
+ onClick: e => e.stopPropagation()
110
+ }, filterBubbleProps), children: filterButton }) })] })
104
111
  : title)
105
112
  ];
106
113
  }) }, i));
@@ -8,6 +8,8 @@ type FilterSharedProps = {
8
8
  export interface FilterOptionsProps extends FilterSharedProps, OptionsBaseProps<MenuOptionType> {
9
9
  /** 默认为`true` */
10
10
  multiple?: boolean;
11
+ /** 默认为`false` */
12
+ searchable?: boolean;
11
13
  }
12
14
  export interface FilterControlProps extends FilterSharedProps {
13
15
  control: FormItemChildren;
@@ -4,35 +4,45 @@ import { useFlatSelection } from '../selectionContext';
4
4
  import { Flex } from '../flex';
5
5
  import { Button } from '../button';
6
6
  import { usePopperContext } from '../popper';
7
- import { memo, useEffect } from 'react';
7
+ import { memo, useDeferredValue, useEffect, useState } from 'react';
8
8
  import { FormItem, useFormContext, useFormValueContext } from '../form';
9
+ import { style } from './filterBubbleContent.style';
10
+ import { Input } from '../input';
11
+ import { Icon } from '../icon';
12
+ import { faSearch } from '@fortawesome/free-solid-svg-icons';
13
+ import { useUpdateEffect } from '../../utils';
9
14
  export const FilterBubbleContent = memo(({ columnKey, columnFilterProps }) => {
10
15
  const { formRef } = useFormContext();
11
- /**
12
- * ------------------------------------------------------------------------------------
13
- * 弹框关闭时触发筛选
14
- */
15
16
  const { open, setOpen } = usePopperContext();
16
17
  useEffect(() => {
17
- !open && formRef.current.submit().then();
18
+ if (!open && !('control' in columnFilterProps) && columnFilterProps.multiple) {
19
+ // 多选模式下,关闭弹框触发筛选
20
+ formRef.current.submit().then();
21
+ }
18
22
  }, [open]);
19
23
  return (_jsxs(_Fragment, { children: [_jsx(FormItem, { field: columnKey, children: 'control' in columnFilterProps
20
24
  ? columnFilterProps.control
21
- : _jsx(FilterOptions, { ...columnFilterProps }) }), columnFilterProps.showButton !== false
22
- ? _jsx(Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: _jsx(Button, { variant: "text", onClick: () => {
25
+ : _jsx(FilterOptions, { ...columnFilterProps, onChange: value => {
26
+ columnFilterProps.onChange?.(value);
27
+ !columnFilterProps.multiple && setOpen(false);
28
+ } }) }), columnFilterProps.showButton !== false &&
29
+ _jsx(Flex, { gap: 6, justifyContent: "center", marginTop: 6, children: _jsx(Button, { variant: "text", onClick: () => {
23
30
  formRef.current.setFieldValue(columnKey, null);
24
31
  setOpen(false);
25
- }, children: "\u91CD\u7F6E" }) })
26
- : _jsx(TriggerFilterOnChange, {})] }));
32
+ }, children: "\u91CD\u7F6E" }) }), !('control' in columnFilterProps) && !columnFilterProps.multiple &&
33
+ // 单选模式,变化即触发筛选
34
+ _jsx(TriggerFilterOnChange, {})] }));
27
35
  });
28
- const FilterOptions = memo(({ multiple = true, showButton = true, value, onChange, ...props }) => {
36
+ const FilterOptions = memo(({ multiple = true, showButton = true, searchable = false, value, onChange, ...props }) => {
29
37
  const [selectedValue, toggleSelect] = useFlatSelection({ multiple, value, onChange });
30
- return (_jsx(OptionsBase, { showCheckbox: multiple, ...props, selectedValue: selectedValue, onToggleSelected: toggleSelect }));
38
+ const [searchValue, setSearchValue] = useState('');
39
+ const deferredSearchValue = useDeferredValue(searchValue);
40
+ return (_jsxs("div", { css: style, children: [_jsx(Input, { prefix: _jsx(Icon, { icon: faSearch }), placeholder: "\u641C\u7D22", value: searchValue, onChange: e => setSearchValue(e.target.value) }), _jsx(OptionsBase, { showCheckbox: multiple, ...props, searchValue: deferredSearchValue, selectedValue: selectedValue, onToggleSelected: toggleSelect })] }));
31
41
  });
32
42
  const TriggerFilterOnChange = memo(() => {
33
43
  const { formRef } = useFormContext();
34
44
  const { formValue } = useFormValueContext();
35
- useEffect(() => {
45
+ useUpdateEffect(() => {
36
46
  formRef.current.submit().then();
37
47
  }, [formValue]);
38
48
  return null;
@@ -0,0 +1 @@
1
+ export declare const style: import("@emotion/react").SerializedStyles;
@@ -0,0 +1,6 @@
1
+ import { css } from '@emotion/react';
2
+ export const style = css `
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 4px
6
+ `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canlooks/can-ui",
3
- "version": "0.0.139",
3
+ "version": "0.0.141",
4
4
  "author": "C.CanLiang <canlooks@gmail.com>",
5
5
  "description": "My ui framework",
6
6
  "license": "MIT",