@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.
- package/dist/cjs/components/curd/curd.js +10 -5
- package/dist/cjs/components/dataGrid/dataGrid.d.ts +2 -0
- package/dist/cjs/components/dataGrid/dataGrid.js +3 -3
- package/dist/cjs/components/dataGrid/dataGridHead.d.ts +1 -0
- package/dist/cjs/components/dataGrid/dataGridHead.js +9 -2
- package/dist/cjs/components/dataGrid/filterBubbleContent.d.ts +2 -0
- package/dist/cjs/components/dataGrid/filterBubbleContent.js +22 -12
- package/dist/cjs/components/dataGrid/filterBubbleContent.style.d.ts +1 -0
- package/dist/cjs/components/dataGrid/filterBubbleContent.style.js +9 -0
- package/dist/esm/components/curd/curd.js +10 -5
- package/dist/esm/components/dataGrid/dataGrid.d.ts +2 -0
- package/dist/esm/components/dataGrid/dataGrid.js +3 -3
- package/dist/esm/components/dataGrid/dataGridHead.d.ts +1 -0
- package/dist/esm/components/dataGrid/dataGridHead.js +10 -3
- package/dist/esm/components/dataGrid/filterBubbleContent.d.ts +2 -0
- package/dist/esm/components/dataGrid/filterBubbleContent.js +23 -13
- package/dist/esm/components/dataGrid/filterBubbleContent.style.d.ts +1 -0
- package/dist/esm/components/dataGrid/filterBubbleContent.style.js +6 -0
- package/package.json +1 -1
|
@@ -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
|
|
63
|
-
|
|
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,
|
|
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:
|
|
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, {
|
|
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 &&
|
|
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
|
|
25
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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;
|
|
@@ -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
|
|
60
|
-
|
|
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,
|
|
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:
|
|
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, {
|
|
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 &&
|
|
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
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|