@oceanbase/design 1.0.0-alpha.17 → 1.0.0-alpha.18
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/design.min.js +1 -1
- package/es/_util/genComponentStyleHook.js +6 -2
- package/es/config-provider/index.d.ts +2 -0
- package/es/config-provider/index.js +68 -38
- package/es/filter/FilterContext.d.ts +1 -1
- package/es/filter/components/FilterButton.js +30 -7
- package/es/filter/components/FilterCascader/components/FlatCascaderContent/index.d.ts +4 -3
- package/es/filter/components/FilterCascader/components/FlatCascaderContent/index.js +20 -6
- package/es/filter/components/FilterCascader/components/NormalCascaderContent.js +2 -7
- package/es/filter/components/FilterInput.d.ts +2 -0
- package/es/filter/components/FilterInput.js +18 -4
- package/es/filter/components/FilterSlot.d.ts +28 -0
- package/es/filter/components/FilterSlot.js +189 -0
- package/es/filter/components/FilterWrap.js +9 -0
- package/es/filter/components/ResponsiveFilterGroup.js +38 -2
- package/es/filter/index.d.ts +2 -0
- package/es/filter/index.js +3 -1
- package/es/filter/style/index.js +1 -1
- package/es/filter/type.d.ts +2 -0
- package/es/table/index.d.ts +2 -2
- package/es/table/style/index.js +34 -16
- package/es/theme/default.d.ts +12 -0
- package/es/theme/default.js +27 -5
- package/lib/_util/genComponentStyleHook.js +6 -2
- package/lib/config-provider/index.d.ts +2 -0
- package/lib/config-provider/index.js +38 -2
- package/lib/filter/FilterContext.d.ts +1 -1
- package/lib/filter/components/FilterButton.js +22 -4
- package/lib/filter/components/FilterCascader/components/FlatCascaderContent/index.d.ts +4 -3
- package/lib/filter/components/FilterCascader/components/FlatCascaderContent/index.js +12 -5
- package/lib/filter/components/FilterCascader/components/NormalCascaderContent.js +2 -7
- package/lib/filter/components/FilterInput.d.ts +2 -0
- package/lib/filter/components/FilterInput.js +18 -3
- package/lib/filter/components/FilterSlot.d.ts +28 -0
- package/lib/filter/components/FilterSlot.js +174 -0
- package/lib/filter/components/FilterWrap.js +8 -0
- package/lib/filter/components/ResponsiveFilterGroup.js +32 -2
- package/lib/filter/index.d.ts +2 -0
- package/lib/filter/index.js +3 -1
- package/lib/filter/style/index.js +1 -1
- package/lib/filter/type.d.ts +2 -0
- package/lib/table/index.d.ts +2 -2
- package/lib/table/style/index.js +28 -19
- package/lib/theme/default.d.ts +12 -0
- package/lib/theme/default.js +29 -6
- package/package.json +2 -2
|
@@ -37,6 +37,7 @@ const FilterButton = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
37
37
|
_isInWrapComponent = false,
|
|
38
38
|
_isFlat = false,
|
|
39
39
|
style,
|
|
40
|
+
allowClear = true,
|
|
40
41
|
...restProps
|
|
41
42
|
}, ref) => {
|
|
42
43
|
const {
|
|
@@ -46,6 +47,7 @@ const FilterButton = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
46
47
|
isCollapsed
|
|
47
48
|
} = (0, _FilterContext.useFilterContext)();
|
|
48
49
|
const [open, setOpen] = (0, _react.useState)(false);
|
|
50
|
+
const [popoverWidth, setPopoverWidth] = (0, _react.useState)();
|
|
49
51
|
const {
|
|
50
52
|
wrapSSR,
|
|
51
53
|
prefixCls
|
|
@@ -77,11 +79,24 @@ const FilterButton = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
77
79
|
const handleOpenChange = newOpen => {
|
|
78
80
|
if (!disabled) {
|
|
79
81
|
setOpen(newOpen);
|
|
80
|
-
// 调用外部传入的 onOpenChange 回调,让父组件能够实时监听状态变化
|
|
81
82
|
externalOnOpenChange?.(newOpen);
|
|
82
83
|
}
|
|
83
84
|
};
|
|
84
85
|
|
|
86
|
+
// 折叠模式下实时监听按钮宽度变化,同步到 Popover 面板宽度
|
|
87
|
+
(0, _react.useEffect)(() => {
|
|
88
|
+
if (!open || !isCollapsed || _isInWrapComponent || !innerRef.current) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const el = innerRef.current;
|
|
92
|
+
setPopoverWidth(el.offsetWidth);
|
|
93
|
+
const observer = new ResizeObserver(() => {
|
|
94
|
+
setPopoverWidth(el.offsetWidth);
|
|
95
|
+
});
|
|
96
|
+
observer.observe(el);
|
|
97
|
+
return () => observer.disconnect();
|
|
98
|
+
}, [open, isCollapsed, _isInWrapComponent]);
|
|
99
|
+
|
|
85
100
|
// 使用 useMemo 缓存 content,避免每次都重新创建
|
|
86
101
|
const popoverContent = (0, _react.useMemo)(() => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
87
102
|
children: [!_isFlat && (!isCollapsed || _isInWrapComponent) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_antd.Flex, {
|
|
@@ -116,7 +131,10 @@ const FilterButton = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
116
131
|
body: {
|
|
117
132
|
padding: 0,
|
|
118
133
|
maxWidth: 300,
|
|
119
|
-
minWidth: 120
|
|
134
|
+
minWidth: 120,
|
|
135
|
+
...(isCollapsed && !_isInWrapComponent && popoverWidth ? {
|
|
136
|
+
width: popoverWidth
|
|
137
|
+
} : {})
|
|
120
138
|
}
|
|
121
139
|
},
|
|
122
140
|
...popoverProps,
|
|
@@ -153,11 +171,11 @@ const FilterButton = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
|
153
171
|
}) : showSuffixIcon ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
154
172
|
className: (0, _style.getFilterCls)(prefixCls, 'icon-wrapper'),
|
|
155
173
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.DownOutlined, {
|
|
156
|
-
className: selected ? (0, _style.getFilterCls)(prefixCls, 'arrow-icon') : '',
|
|
174
|
+
className: selected && allowClear ? (0, _style.getFilterCls)(prefixCls, 'arrow-icon') : '',
|
|
157
175
|
style: disabled ? {
|
|
158
176
|
color: 'var(--ob-color-icon-disabled)'
|
|
159
177
|
} : undefined
|
|
160
|
-
}), selected && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
178
|
+
}), selected && allowClear && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
161
179
|
className: (0, _style.getFilterCls)(prefixCls, 'clear-icon'),
|
|
162
180
|
onClick: e => {
|
|
163
181
|
if (!disabled) {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { CascaderPanelProps } from 'antd';
|
|
2
3
|
import type { CascaderOption } from '../../types';
|
|
3
4
|
import type { FilterButtonRef } from '../../../FilterButton';
|
|
4
|
-
interface FlatCascaderContentProps {
|
|
5
|
+
interface FlatCascaderContentProps extends CascaderPanelProps {
|
|
5
6
|
options: CascaderOption[];
|
|
6
|
-
currentValue: string[][];
|
|
7
|
+
currentValue: (string | number)[][];
|
|
7
8
|
multiple: boolean;
|
|
8
9
|
filterButtonRef: React.RefObject<FilterButtonRef>;
|
|
9
|
-
onValueChange: (value: string[][]) => void;
|
|
10
|
+
onValueChange: (value: (string | number)[][]) => void;
|
|
10
11
|
}
|
|
11
12
|
/**
|
|
12
13
|
* Flat 模式的级联内容容器组件
|
|
@@ -23,7 +23,8 @@ const FlatCascaderContent = ({
|
|
|
23
23
|
currentValue,
|
|
24
24
|
filterButtonRef,
|
|
25
25
|
multiple = false,
|
|
26
|
-
onValueChange
|
|
26
|
+
onValueChange,
|
|
27
|
+
...restProps
|
|
27
28
|
}) => {
|
|
28
29
|
// 将组件内部的值格式转换为 Cascader.Panel 需要的格式
|
|
29
30
|
// 组件内部:[[parent, child], ...] 或 [[parent, child]]
|
|
@@ -43,7 +44,7 @@ const FlatCascaderContent = ({
|
|
|
43
44
|
}, [currentValue, multiple]);
|
|
44
45
|
|
|
45
46
|
// 处理 Cascader.Panel 的值变化
|
|
46
|
-
const handleCascaderChange =
|
|
47
|
+
const handleCascaderChange = value => {
|
|
47
48
|
if (multiple) {
|
|
48
49
|
// 多选:value 是 string[][],如 [['frontend', 'react'], ['backend', 'java']]
|
|
49
50
|
onValueChange(value);
|
|
@@ -55,16 +56,22 @@ const FlatCascaderContent = ({
|
|
|
55
56
|
};
|
|
56
57
|
|
|
57
58
|
// 使用条件渲染来处理 multiple 属性的类型问题
|
|
58
|
-
return multiple ?
|
|
59
|
+
return multiple ?
|
|
60
|
+
/*#__PURE__*/
|
|
61
|
+
// @ts-ignore-next-line
|
|
62
|
+
(0, _jsxRuntime.jsx)(_antd.Cascader.Panel, {
|
|
59
63
|
options: options,
|
|
60
64
|
value: cascaderValue,
|
|
61
65
|
onChange: handleCascaderChange,
|
|
62
|
-
multiple: multiple
|
|
66
|
+
multiple: multiple,
|
|
67
|
+
showCheckedStrategy: _antd.Cascader.SHOW_CHILD,
|
|
68
|
+
...restProps
|
|
63
69
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Cascader.Panel, {
|
|
64
70
|
options: options,
|
|
65
71
|
value: cascaderValue,
|
|
66
72
|
onChange: handleCascaderChange,
|
|
67
|
-
multiple: false
|
|
73
|
+
multiple: false,
|
|
74
|
+
...restProps
|
|
68
75
|
});
|
|
69
76
|
};
|
|
70
77
|
exports.FlatCascaderContent = FlatCascaderContent;
|
|
@@ -11,7 +11,6 @@ var _theme = _interopRequireDefault(require("../../../../theme"));
|
|
|
11
11
|
var _input = _interopRequireDefault(require("../../../../input"));
|
|
12
12
|
var _empty = _interopRequireDefault(require("../../../../empty"));
|
|
13
13
|
var _icons = require("@oceanbase/icons");
|
|
14
|
-
var _classnames = _interopRequireDefault(require("classnames"));
|
|
15
14
|
var _style = require("../../../style");
|
|
16
15
|
var _constants = require("../constants");
|
|
17
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
@@ -109,9 +108,7 @@ const NormalCascaderContent = ({
|
|
|
109
108
|
},
|
|
110
109
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_antd.Flex, {
|
|
111
110
|
gap: _constants.GAP_SIZE_SMALL * 2,
|
|
112
|
-
className: (0,
|
|
113
|
-
[(0, _style.getFilterCls)(prefixCls, 'has-selected')]: isNodeSelected
|
|
114
|
-
}),
|
|
111
|
+
className: (0, _style.getFilterCls)(prefixCls, 'select-option'),
|
|
115
112
|
justify: "space-between",
|
|
116
113
|
align: "center",
|
|
117
114
|
onClick: handleNodeClick,
|
|
@@ -207,9 +204,7 @@ const NormalCascaderContent = ({
|
|
|
207
204
|
},
|
|
208
205
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_antd.Flex, {
|
|
209
206
|
gap: _constants.GAP_SIZE_SMALL * 2,
|
|
210
|
-
className: (0,
|
|
211
|
-
[(0, _style.getFilterCls)(prefixCls, 'has-selected')]: hasSelectedChildren
|
|
212
|
-
}),
|
|
207
|
+
className: (0, _style.getFilterCls)(prefixCls, 'select-option'),
|
|
213
208
|
justify: "space-between",
|
|
214
209
|
align: "center",
|
|
215
210
|
style: {
|
|
@@ -11,6 +11,8 @@ export interface FilterInputProps extends BaseFilterProps {
|
|
|
11
11
|
inputProps?: InputProps;
|
|
12
12
|
/** Switch 组件的额外属性 */
|
|
13
13
|
switchProps?: SwitchProps;
|
|
14
|
+
/** 是否显示开关,默认为 false */
|
|
15
|
+
showSwitch?: boolean;
|
|
14
16
|
}
|
|
15
17
|
declare const FilterInput: FC<FilterInputProps>;
|
|
16
18
|
export default FilterInput;
|
|
@@ -24,6 +24,7 @@ const FilterInput = ({
|
|
|
24
24
|
bordered = true,
|
|
25
25
|
inputProps,
|
|
26
26
|
switchProps,
|
|
27
|
+
showSwitch,
|
|
27
28
|
...restProps
|
|
28
29
|
}) => {
|
|
29
30
|
const {
|
|
@@ -76,13 +77,15 @@ const FilterInput = ({
|
|
|
76
77
|
align: "center",
|
|
77
78
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
78
79
|
children: label
|
|
79
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_switch.default, {
|
|
80
|
+
}), showSwitch && /*#__PURE__*/(0, _jsxRuntime.jsx)(_switch.default, {
|
|
80
81
|
checked: switchValue,
|
|
81
82
|
onChange: val => setSwitchValue(val),
|
|
82
83
|
size: "small",
|
|
83
84
|
...switchProps
|
|
84
85
|
})]
|
|
85
|
-
}),
|
|
86
|
+
}), showSwitch ?
|
|
87
|
+
// 有开关:根据 switchValue 决定是否显示 Input
|
|
88
|
+
switchValue && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
86
89
|
style: {
|
|
87
90
|
marginTop: 8
|
|
88
91
|
},
|
|
@@ -91,7 +94,19 @@ const FilterInput = ({
|
|
|
91
94
|
onChange: handleChange,
|
|
92
95
|
...inputProps
|
|
93
96
|
})
|
|
94
|
-
}) :
|
|
97
|
+
}) :
|
|
98
|
+
/*#__PURE__*/
|
|
99
|
+
// 无开关:直接显示 Input
|
|
100
|
+
(0, _jsxRuntime.jsx)("div", {
|
|
101
|
+
style: {
|
|
102
|
+
marginTop: 8
|
|
103
|
+
},
|
|
104
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_input.default, {
|
|
105
|
+
value: currentValue,
|
|
106
|
+
onChange: handleChange,
|
|
107
|
+
...inputProps
|
|
108
|
+
})
|
|
109
|
+
})]
|
|
95
110
|
});
|
|
96
111
|
|
|
97
112
|
// 如果处于折叠模式,只渲染内容部分
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { FC, ReactNode } from 'react';
|
|
2
|
+
import type { BaseFilterProps, InternalFilterProps } from '../type';
|
|
3
|
+
export interface FilterSlotProps extends BaseFilterProps, InternalFilterProps {
|
|
4
|
+
/**
|
|
5
|
+
* 直接渲染的自定义内容,不包裹 FilterButton + Popover。
|
|
6
|
+
* Filter.Slot 仅作为响应式收集的包裹容器,
|
|
7
|
+
* 会通过 cloneElement 自动注入 value/onChange。
|
|
8
|
+
*/
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* Popover 弹框中的自定义筛选内容。
|
|
12
|
+
* 设置后使用 FilterButton + Popover 模式,
|
|
13
|
+
* 会通过 cloneElement 自动注入 value/onChange。
|
|
14
|
+
*/
|
|
15
|
+
dropdownRender?: ReactNode;
|
|
16
|
+
/** 当前筛选值(受控) */
|
|
17
|
+
value?: any;
|
|
18
|
+
/** 默认筛选值(非受控) */
|
|
19
|
+
defaultValue?: any;
|
|
20
|
+
/** 值变化回调 */
|
|
21
|
+
onChange?: (value: any) => void;
|
|
22
|
+
/** 将 value 格式化为展示文本,用于 FilterButton 标签和折叠态 Tooltip */
|
|
23
|
+
formatValue?: (value: any) => string;
|
|
24
|
+
/** 未选值时的占位文本 */
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
}
|
|
27
|
+
declare const FilterSlot: FC<FilterSlotProps>;
|
|
28
|
+
export default FilterSlot;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _theme = _interopRequireDefault(require("../../theme"));
|
|
9
|
+
var _useControlledState = require("../hooks/useControlledState");
|
|
10
|
+
var _FilterContext = require("../FilterContext");
|
|
11
|
+
var _useFilterCollapsed = require("../hooks/useFilterCollapsed");
|
|
12
|
+
var _useFilterTooltip = require("../hooks/useFilterTooltip");
|
|
13
|
+
var _style = _interopRequireWildcard(require("../style"));
|
|
14
|
+
var _utils = require("../utils");
|
|
15
|
+
var _FilterButton = _interopRequireDefault(require("./FilterButton"));
|
|
16
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
19
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
20
|
+
const FilterSlot = ({
|
|
21
|
+
children,
|
|
22
|
+
dropdownRender,
|
|
23
|
+
value,
|
|
24
|
+
defaultValue,
|
|
25
|
+
onChange,
|
|
26
|
+
formatValue,
|
|
27
|
+
placeholder,
|
|
28
|
+
icon,
|
|
29
|
+
label,
|
|
30
|
+
bordered = true,
|
|
31
|
+
loading = false,
|
|
32
|
+
_isCollapsed = false,
|
|
33
|
+
...restProps
|
|
34
|
+
}) => {
|
|
35
|
+
const isCollapsed = (0, _useFilterCollapsed.useFilterCollapsed)(_isCollapsed);
|
|
36
|
+
const {
|
|
37
|
+
token
|
|
38
|
+
} = _theme.default.useToken();
|
|
39
|
+
const {
|
|
40
|
+
prefixCls
|
|
41
|
+
} = (0, _style.default)();
|
|
42
|
+
const filterButtonRef = (0, _react.useRef)(null);
|
|
43
|
+
const {
|
|
44
|
+
updateFilterValue
|
|
45
|
+
} = (0, _FilterContext.useFilterContext)();
|
|
46
|
+
const filterId = (0, _react.useMemo)(() => (0, _utils.generateFilterId)('slot', label), [label]);
|
|
47
|
+
const {
|
|
48
|
+
onOpenChange: externalOnOpenChange,
|
|
49
|
+
...filterButtonProps
|
|
50
|
+
} = restProps;
|
|
51
|
+
const [currentValue, setValue] = (0, _useControlledState.useControlledState)(value, defaultValue, onChange);
|
|
52
|
+
const hasValue = currentValue !== undefined && currentValue !== null && currentValue !== '';
|
|
53
|
+
const formattedText = hasValue && formatValue ? formatValue(currentValue) : '';
|
|
54
|
+
const displayText = hasValue ? formattedText || String(currentValue) : '';
|
|
55
|
+
const currentLabel = hasValue && displayText ? displayText : label;
|
|
56
|
+
const isDirectRender = !dropdownRender;
|
|
57
|
+
const {
|
|
58
|
+
onPopoverOpenChange,
|
|
59
|
+
wrapWithTooltip
|
|
60
|
+
} = (0, _useFilterTooltip.useFilterTooltip)({
|
|
61
|
+
hasValue,
|
|
62
|
+
label,
|
|
63
|
+
content: displayText || null,
|
|
64
|
+
disabled: isCollapsed || isDirectRender
|
|
65
|
+
});
|
|
66
|
+
const handlePopoverOpenChange = open => {
|
|
67
|
+
onPopoverOpenChange(open);
|
|
68
|
+
externalOnOpenChange?.(open);
|
|
69
|
+
};
|
|
70
|
+
(0, _react.useEffect)(() => {
|
|
71
|
+
if (isCollapsed && updateFilterValue) {
|
|
72
|
+
updateFilterValue(filterId, label, currentValue, [{
|
|
73
|
+
formattedText
|
|
74
|
+
}], 'slot');
|
|
75
|
+
}
|
|
76
|
+
}, [isCollapsed, updateFilterValue, filterId, label, currentValue, formattedText]);
|
|
77
|
+
const handleClear = () => {
|
|
78
|
+
setValue(undefined);
|
|
79
|
+
};
|
|
80
|
+
const handleChildChange = (0, _react.useCallback)((...args) => {
|
|
81
|
+
const firstArg = args[0];
|
|
82
|
+
let newValue;
|
|
83
|
+
if (firstArg && typeof firstArg === 'object' && 'target' in firstArg && typeof firstArg.target === 'object') {
|
|
84
|
+
newValue = 'value' in firstArg.target ? firstArg.target.value : firstArg.target.checked;
|
|
85
|
+
} else {
|
|
86
|
+
newValue = firstArg;
|
|
87
|
+
}
|
|
88
|
+
setValue(newValue);
|
|
89
|
+
}, [setValue]);
|
|
90
|
+
const injectValueProps = (0, _react.useCallback)(element => {
|
|
91
|
+
if ( /*#__PURE__*/(0, _react.isValidElement)(element)) {
|
|
92
|
+
const childElement = element;
|
|
93
|
+
const originalOnChange = childElement.props?.onChange;
|
|
94
|
+
return /*#__PURE__*/_react.default.cloneElement(childElement, {
|
|
95
|
+
value: currentValue,
|
|
96
|
+
onChange: (...args) => {
|
|
97
|
+
handleChildChange(...args);
|
|
98
|
+
originalOnChange?.(...args);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return element;
|
|
103
|
+
}, [currentValue, handleChildChange]);
|
|
104
|
+
|
|
105
|
+
// ======== 直接渲染模式(仅 children,无 dropdownRender) ========
|
|
106
|
+
if (isDirectRender) {
|
|
107
|
+
if (isCollapsed) {
|
|
108
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
109
|
+
style: {
|
|
110
|
+
paddingBlock: token.paddingXXS
|
|
111
|
+
},
|
|
112
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
113
|
+
style: {
|
|
114
|
+
marginBottom: 8
|
|
115
|
+
},
|
|
116
|
+
children: label
|
|
117
|
+
}), injectValueProps(children)]
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
121
|
+
children: injectValueProps(children)
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ======== Popover 模式(设置了 dropdownRender) ========
|
|
126
|
+
const wrappedContent = (0, _utils.wrapContent)(injectValueProps(dropdownRender));
|
|
127
|
+
if (isCollapsed) {
|
|
128
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
129
|
+
style: {
|
|
130
|
+
paddingBlock: token.paddingXXS
|
|
131
|
+
},
|
|
132
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
133
|
+
style: {
|
|
134
|
+
marginBottom: 8
|
|
135
|
+
},
|
|
136
|
+
children: label
|
|
137
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_FilterButton.default, {
|
|
138
|
+
ref: filterButtonRef,
|
|
139
|
+
icon: icon,
|
|
140
|
+
label: label,
|
|
141
|
+
bordered: bordered,
|
|
142
|
+
onClear: handleClear,
|
|
143
|
+
content: wrappedContent,
|
|
144
|
+
loading: loading,
|
|
145
|
+
selected: hasValue,
|
|
146
|
+
onOpenChange: handlePopoverOpenChange,
|
|
147
|
+
...filterButtonProps,
|
|
148
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
149
|
+
className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
|
|
150
|
+
style: (0, _utils.getWrappedValueStyle)(hasValue),
|
|
151
|
+
children: hasValue ? displayText : placeholder || (0, _utils.getPlaceholder)()
|
|
152
|
+
})
|
|
153
|
+
})]
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const filterButton = /*#__PURE__*/(0, _jsxRuntime.jsx)(_FilterButton.default, {
|
|
157
|
+
ref: filterButtonRef,
|
|
158
|
+
icon: icon,
|
|
159
|
+
label: label,
|
|
160
|
+
bordered: bordered,
|
|
161
|
+
onClear: handleClear,
|
|
162
|
+
content: wrappedContent,
|
|
163
|
+
loading: loading,
|
|
164
|
+
selected: hasValue,
|
|
165
|
+
onOpenChange: handlePopoverOpenChange,
|
|
166
|
+
...filterButtonProps,
|
|
167
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
168
|
+
className: (0, _style.getFilterCls)(prefixCls, 'text-ellipsis'),
|
|
169
|
+
children: hasValue ? currentLabel : placeholder || label
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
return wrapWithTooltip(filterButton);
|
|
173
|
+
};
|
|
174
|
+
var _default = exports.default = FilterSlot;
|
|
@@ -142,6 +142,14 @@ const FilterWrap = ({
|
|
|
142
142
|
{
|
|
143
143
|
return String(value);
|
|
144
144
|
}
|
|
145
|
+
case 'slot':
|
|
146
|
+
{
|
|
147
|
+
const slotMeta = options;
|
|
148
|
+
if (slotMeta?.[0]?.formattedText) {
|
|
149
|
+
return slotMeta[0].formattedText;
|
|
150
|
+
}
|
|
151
|
+
return String(value);
|
|
152
|
+
}
|
|
145
153
|
default:
|
|
146
154
|
{
|
|
147
155
|
return String(value);
|
|
@@ -180,6 +180,34 @@ const ResponsiveFilterGroup = ({
|
|
|
180
180
|
setVisibleCount(prev => prev === count ? prev : count);
|
|
181
181
|
}, [filterValues]);
|
|
182
182
|
|
|
183
|
+
// Effect 4: 监听子元素的宽度变化(如筛选值变化导致按钮变宽),
|
|
184
|
+
// 更新缓存宽度并重新计算可见数量。
|
|
185
|
+
// 依赖 visibleCount 以便在显隐切换后重新查询 DOM 元素。
|
|
186
|
+
(0, _react.useEffect)(() => {
|
|
187
|
+
if (!containerRef.current || isMeasuring) return;
|
|
188
|
+
const el = containerRef.current;
|
|
189
|
+
const items = el.querySelectorAll('[data-filter-item]');
|
|
190
|
+
if (items.length === 0) return;
|
|
191
|
+
const ro = new ResizeObserver(() => {
|
|
192
|
+
let widthChanged = false;
|
|
193
|
+
items.forEach(item => {
|
|
194
|
+
const idx = Number(item.dataset.filterItem);
|
|
195
|
+
if (isNaN(idx)) return;
|
|
196
|
+
const w = item.offsetWidth;
|
|
197
|
+
if (w > 0 && Math.abs(w - (cachedWidths.current[idx] || 0)) > 1) {
|
|
198
|
+
cachedWidths.current[idx] = w;
|
|
199
|
+
widthChanged = true;
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
if (widthChanged) {
|
|
203
|
+
const count = calculateRef.current(el.offsetWidth);
|
|
204
|
+
setVisibleCount(prev => prev === count ? prev : count);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
items.forEach(item => ro.observe(item));
|
|
208
|
+
return () => ro.disconnect();
|
|
209
|
+
}, [isMeasuring, visibleCount]);
|
|
210
|
+
|
|
183
211
|
// --- 派生状态 ---
|
|
184
212
|
const visibleIndexSet = (0, _react.useMemo)(() => {
|
|
185
213
|
if (visibleCount === null) return null;
|
|
@@ -317,9 +345,10 @@ const ResponsiveFilterGroup = ({
|
|
|
317
345
|
filterValues: filterValues,
|
|
318
346
|
updateFilterValue: updateFilterValue,
|
|
319
347
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
320
|
-
"data-filter-item":
|
|
348
|
+
"data-filter-item": index,
|
|
321
349
|
style: {
|
|
322
|
-
display
|
|
350
|
+
display,
|
|
351
|
+
flexShrink: 0
|
|
323
352
|
},
|
|
324
353
|
children: child
|
|
325
354
|
})
|
|
@@ -345,6 +374,7 @@ const ResponsiveFilterGroup = ({
|
|
|
345
374
|
flex: '1 1 auto',
|
|
346
375
|
minWidth: 0,
|
|
347
376
|
position: 'relative',
|
|
377
|
+
overflow: 'hidden',
|
|
348
378
|
visibility: isMeasuring ? 'hidden' : undefined,
|
|
349
379
|
...style
|
|
350
380
|
},
|
package/lib/filter/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type { FilterCascaderProps, CascaderOption } from './components/FilterCas
|
|
|
7
7
|
export type { FilterSwitchProps } from './components/FilterSwitch';
|
|
8
8
|
export type { FilterRangeProps, RangeOption } from './components/FilterRange';
|
|
9
9
|
export type { FilterInputProps } from './components/FilterInput';
|
|
10
|
+
export type { FilterSlotProps } from './components/FilterSlot';
|
|
10
11
|
export type { FilterWrapProps } from './components/FilterWrap';
|
|
11
12
|
export type { ResponsiveFilterGroupProps } from './components/ResponsiveFilterGroup';
|
|
12
13
|
declare const Filter: {
|
|
@@ -17,6 +18,7 @@ declare const Filter: {
|
|
|
17
18
|
Cascader: import("react").FC<import("./components/FilterCascader/types").FilterCascaderProps>;
|
|
18
19
|
Switch: import("react").FC<import("./components/FilterSwitch").FilterSwitchProps>;
|
|
19
20
|
Input: import("react").FC<import("./components/FilterInput").FilterInputProps>;
|
|
21
|
+
Slot: import("react").FC<import("./components/FilterSlot").FilterSlotProps>;
|
|
20
22
|
ResponsiveGroup: import("react").FC<import("./components/ResponsiveFilterGroup").ResponsiveFilterGroupProps>;
|
|
21
23
|
};
|
|
22
24
|
export default Filter;
|
package/lib/filter/index.js
CHANGED
|
@@ -21,6 +21,7 @@ var _FilterCheckbox = _interopRequireDefault(require("./components/FilterCheckbo
|
|
|
21
21
|
var _FilterRange = _interopRequireDefault(require("./components/FilterRange"));
|
|
22
22
|
var _FilterInput = _interopRequireDefault(require("./components/FilterInput"));
|
|
23
23
|
var _FilterSelect = _interopRequireDefault(require("./components/FilterSelect"));
|
|
24
|
+
var _FilterSlot = _interopRequireDefault(require("./components/FilterSlot"));
|
|
24
25
|
var _FilterSwitch = _interopRequireDefault(require("./components/FilterSwitch"));
|
|
25
26
|
var _FilterWrap = _interopRequireDefault(require("./components/FilterWrap"));
|
|
26
27
|
var _ResponsiveFilterGroup = _interopRequireDefault(require("./components/ResponsiveFilterGroup"));
|
|
@@ -34,10 +35,11 @@ const Filter = {
|
|
|
34
35
|
Select: markAsFilterComponent(_FilterSelect.default),
|
|
35
36
|
Checkbox: markAsFilterComponent(_FilterCheckbox.default),
|
|
36
37
|
Range: markAsFilterComponent(_FilterRange.default),
|
|
37
|
-
Wrap: _FilterWrap.default,
|
|
38
|
+
Wrap: markAsFilterComponent(_FilterWrap.default),
|
|
38
39
|
Cascader: markAsFilterComponent(_index.default),
|
|
39
40
|
Switch: markAsFilterComponent(_FilterSwitch.default),
|
|
40
41
|
Input: markAsFilterComponent(_FilterInput.default),
|
|
42
|
+
Slot: markAsFilterComponent(_FilterSlot.default),
|
|
41
43
|
ResponsiveGroup: _ResponsiveFilterGroup.default
|
|
42
44
|
};
|
|
43
45
|
var _default = exports.default = Filter;
|
package/lib/filter/type.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface BaseFilterProps extends Omit<PopoverProps, 'title' | 'content'
|
|
|
21
21
|
alwaysCollapse?: boolean;
|
|
22
22
|
/** 是否显示后缀图标区域(包括下拉箭头和清除图标),默认 true */
|
|
23
23
|
showSuffixIcon?: boolean;
|
|
24
|
+
/** 是否显示清除按钮,默认 true */
|
|
25
|
+
allowClear?: boolean;
|
|
24
26
|
}
|
|
25
27
|
/** 内部属性,用于标记组件是否在折叠模式中 */
|
|
26
28
|
export interface InternalFilterProps {
|
package/lib/table/index.d.ts
CHANGED
|
@@ -38,8 +38,8 @@ declare const _default: (<RecordType extends AnyObject = AnyObject>(props: Table
|
|
|
38
38
|
SELECTION_ALL: "SELECT_ALL";
|
|
39
39
|
SELECTION_INVERT: "SELECT_INVERT";
|
|
40
40
|
SELECTION_NONE: "SELECT_NONE";
|
|
41
|
-
Column: <
|
|
42
|
-
ColumnGroup: <
|
|
41
|
+
Column: <RecordType extends import("antd/es/_util/type").AnyObject>(_: import("antd").TableColumnProps<RecordType>) => null;
|
|
42
|
+
ColumnGroup: <RecordType_1 extends import("antd/es/_util/type").AnyObject>(_: import("antd/es/table/ColumnGroup").ColumnGroupProps<RecordType_1>) => null;
|
|
43
43
|
Summary: typeof Summary;
|
|
44
44
|
useStyle: (prefixCls: string, rootCls?: string) => readonly [(node: ReactElement<any, string | React.JSXElementConstructor<any>>) => ReactElement<any, string | React.JSXElementConstructor<any>>, string, string];
|
|
45
45
|
useDefaultPagination: (pagination?: false | import("antd").TablePaginationConfig) => false | import("antd").TablePaginationConfig;
|
package/lib/table/style/index.js
CHANGED
|
@@ -5,25 +5,33 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.genTableStyle = exports.default = void 0;
|
|
7
7
|
var _cssinjs = require("@ant-design/cssinjs");
|
|
8
|
+
var _style = require("antd/es/table/style");
|
|
8
9
|
var _genComponentStyleHook = require("../../_util/genComponentStyleHook");
|
|
10
|
+
/**
|
|
11
|
+
* 单元格是否与全局正文同档(`cellFontSize === token.fontSize`)。
|
|
12
|
+
*/
|
|
13
|
+
const isTableCellBodyFontScale = token => token.cellFontSize === token.fontSize;
|
|
14
|
+
const getTableCellLineHeight = token => isTableCellBodyFontScale(token) ? token.lineHeight : token.lineHeightSM;
|
|
15
|
+
const getTableEmbeddedControlHeight = token => isTableCellBodyFontScale(token) ? token.controlHeight : token.controlHeightSM;
|
|
9
16
|
const genSmallBtnStyle = token => {
|
|
10
17
|
const {
|
|
11
18
|
antCls
|
|
12
19
|
} = token;
|
|
20
|
+
const cellLineHeight = getTableCellLineHeight(token);
|
|
21
|
+
const controlH = getTableEmbeddedControlHeight(token);
|
|
13
22
|
return {
|
|
14
|
-
// button is small size by default
|
|
15
23
|
[`${antCls}-btn:not(${antCls}-btn-sm):not(${antCls}-btn-lg)`]: {
|
|
16
|
-
height:
|
|
17
|
-
fontSize: token.
|
|
18
|
-
lineHeight:
|
|
24
|
+
height: controlH,
|
|
25
|
+
fontSize: token.cellFontSize,
|
|
26
|
+
lineHeight: cellLineHeight,
|
|
19
27
|
[`&:not(${antCls}-btn-icon-only):not(${antCls}-btn-circle)`]: {
|
|
20
28
|
paddingInline: token.paddingXS
|
|
21
29
|
},
|
|
22
30
|
[`&${antCls}-btn-icon-only`]: {
|
|
23
|
-
width:
|
|
31
|
+
width: controlH
|
|
24
32
|
},
|
|
25
33
|
[`&${antCls}-btn-circle`]: {
|
|
26
|
-
minWidth:
|
|
34
|
+
minWidth: controlH
|
|
27
35
|
}
|
|
28
36
|
}
|
|
29
37
|
};
|
|
@@ -46,11 +54,12 @@ const genTableStyle = token => {
|
|
|
46
54
|
marginXS,
|
|
47
55
|
calc
|
|
48
56
|
} = token;
|
|
57
|
+
const cellLineHeight = getTableCellLineHeight(token);
|
|
58
|
+
const embeddedControlH = getTableEmbeddedControlHeight(token);
|
|
49
59
|
return {
|
|
50
60
|
// 表格通用样式
|
|
51
61
|
[`${componentCls}-wrapper ${componentCls}`]: {
|
|
52
|
-
|
|
53
|
-
lineHeight: token.lineHeightSM,
|
|
62
|
+
lineHeight: cellLineHeight,
|
|
54
63
|
color: colorText,
|
|
55
64
|
backgroundColor: colorBgBase,
|
|
56
65
|
borderRadius: borderRadiusLG,
|
|
@@ -137,8 +146,8 @@ const genTableStyle = token => {
|
|
|
137
146
|
},
|
|
138
147
|
a: {
|
|
139
148
|
fontWeight: token.fontWeightStrong,
|
|
140
|
-
// work for ProTable link style
|
|
141
|
-
fontSize: token.
|
|
149
|
+
// work for ProTable link style;与单元格字号一致
|
|
150
|
+
fontSize: token.cellFontSize
|
|
142
151
|
}
|
|
143
152
|
},
|
|
144
153
|
...genSmallBtnStyle(token),
|
|
@@ -418,7 +427,7 @@ const genTableStyle = token => {
|
|
|
418
427
|
[`${componentCls}-wrapper`]: {
|
|
419
428
|
[`${componentCls}-pagination`]: {
|
|
420
429
|
[`&${antCls}-pagination`]: {
|
|
421
|
-
fontSize: token.
|
|
430
|
+
fontSize: token.cellFontSize,
|
|
422
431
|
padding: `${(0, _cssinjs.unit)(token.paddingSM)} 0`,
|
|
423
432
|
margin: 0,
|
|
424
433
|
// 带边框和带内部边框的 Table,分页器右侧间距设为 token.marginLG
|
|
@@ -426,14 +435,14 @@ const genTableStyle = token => {
|
|
|
426
435
|
marginInlineEnd: marginLG
|
|
427
436
|
},
|
|
428
437
|
[`${antCls}-pagination-item, ${antCls}-pagination-total-text, ${antCls}-pagination-prev, ${antCls}-pagination-next`]: {
|
|
429
|
-
height:
|
|
430
|
-
minWidth:
|
|
431
|
-
lineHeight: (0, _cssinjs.unit)(calc(
|
|
438
|
+
height: embeddedControlH,
|
|
439
|
+
minWidth: embeddedControlH,
|
|
440
|
+
lineHeight: (0, _cssinjs.unit)(calc(embeddedControlH).sub(calc(token.lineWidth).mul(2)).equal())
|
|
432
441
|
},
|
|
433
442
|
[`${antCls}-pagination-options ${antCls}-select-single`]: {
|
|
434
|
-
height:
|
|
443
|
+
height: embeddedControlH,
|
|
435
444
|
[`${antCls}-select-selector`]: {
|
|
436
|
-
fontSize: token.
|
|
445
|
+
fontSize: token.cellFontSize,
|
|
437
446
|
paddingInline: calc(token.paddingXS).sub(token.lineWidth).equal()
|
|
438
447
|
}
|
|
439
448
|
}
|
|
@@ -465,7 +474,7 @@ const genTableStyle = token => {
|
|
|
465
474
|
}
|
|
466
475
|
};
|
|
467
476
|
};
|
|
477
|
+
|
|
478
|
+
// 经 genComponentStyleHook 注册为 ['Table','oceanbase']:合并 components.Table,且不与 antd 主 Table 样式钩子冲突。
|
|
468
479
|
exports.genTableStyle = genTableStyle;
|
|
469
|
-
var _default = exports.default = (0, _genComponentStyleHook.genStyleHooks)('Table', token =>
|
|
470
|
-
return [genTableStyle(token)];
|
|
471
|
-
});
|
|
480
|
+
var _default = exports.default = (0, _genComponentStyleHook.genStyleHooks)('Table', token => [genTableStyle(token)], _style.prepareComponentToken);
|