@blocklet/list 0.8.43 → 0.8.46
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.
|
@@ -15,21 +15,15 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
15
15
|
|
|
16
16
|
var _material = require("@mui/material");
|
|
17
17
|
|
|
18
|
-
var _Check = _interopRequireDefault(require("@mui/icons-material/Check"));
|
|
19
|
-
|
|
20
18
|
var _KeyboardArrowDown = _interopRequireDefault(require("@mui/icons-material/KeyboardArrowDown"));
|
|
21
19
|
|
|
22
|
-
var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
|
|
23
|
-
|
|
24
20
|
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
25
21
|
|
|
26
|
-
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
27
|
-
|
|
28
22
|
var _button = _interopRequireDefault(require("./button"));
|
|
29
23
|
|
|
30
24
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
31
25
|
|
|
32
|
-
const _excluded = ["title", "value", "icon", "prepend", "options", "
|
|
26
|
+
const _excluded = ["title", "value", "icon", "prepend", "options", "onChange", "itemRender"];
|
|
33
27
|
|
|
34
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
29
|
|
|
@@ -50,62 +44,37 @@ function CustomSelect(_ref) {
|
|
|
50
44
|
icon,
|
|
51
45
|
prepend,
|
|
52
46
|
options,
|
|
53
|
-
multiple,
|
|
54
|
-
onClose,
|
|
55
|
-
onShow,
|
|
56
47
|
onChange,
|
|
57
|
-
onInput,
|
|
58
48
|
itemRender
|
|
59
49
|
} = _ref,
|
|
60
50
|
buttonProps = _objectWithoutProperties(_ref, _excluded);
|
|
61
51
|
|
|
62
52
|
const anchorRef = (0, _react.useRef)(null);
|
|
63
53
|
const theme = (0, _useTheme.default)();
|
|
64
|
-
const [open, setOpen] = (0, _react.useState)(false);
|
|
65
|
-
|
|
66
|
-
const [currentValue, setCurrentValue] = (0, _react.useState)(value !== null ? value : multiple ? [] : '');
|
|
54
|
+
const [open, setOpen] = (0, _react.useState)(false);
|
|
55
|
+
const [currentValue, setCurrentValue] = (0, _react.useState)(value !== null ? value : '');
|
|
67
56
|
const isSm = (0, _material.useMediaQuery)(theme.breakpoints.down('sm'));
|
|
68
57
|
(0, _react.useEffect)(() => {
|
|
69
|
-
|
|
70
|
-
setCurrentValue(value !== null ? value : multiple ? [] : '');
|
|
58
|
+
setCurrentValue(value !== null ? value : '');
|
|
71
59
|
}, [value]);
|
|
72
|
-
|
|
73
|
-
function closeMenu() {
|
|
74
|
-
(0, _isEqual.default)(value, currentValue) || onInput(currentValue);
|
|
75
|
-
onClose();
|
|
60
|
+
const closeMenu = (0, _react.useCallback)(() => {
|
|
76
61
|
setOpen(false);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function openMenu() {
|
|
62
|
+
}, []);
|
|
63
|
+
const openMenu = (0, _react.useCallback)(() => {
|
|
80
64
|
setOpen(true);
|
|
81
|
-
|
|
82
|
-
}
|
|
65
|
+
}, []);
|
|
83
66
|
|
|
84
67
|
function toggle(option) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const index = copyValue.indexOf(option.value);
|
|
88
|
-
|
|
89
|
-
if (index >= 0) {
|
|
90
|
-
copyValue.splice(index, 1);
|
|
91
|
-
} else {
|
|
92
|
-
copyValue.push(option.value);
|
|
93
|
-
}
|
|
68
|
+
setCurrentValue(option.value);
|
|
69
|
+
onChange(option.value);
|
|
94
70
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} else {
|
|
98
|
-
setCurrentValue(option.value);
|
|
99
|
-
onChange(option.value);
|
|
100
|
-
|
|
101
|
-
if (isSm) {
|
|
102
|
-
closeMenu();
|
|
103
|
-
}
|
|
71
|
+
if (isSm) {
|
|
72
|
+
closeMenu();
|
|
104
73
|
}
|
|
105
74
|
}
|
|
106
75
|
|
|
107
76
|
function containsValue(optionValue) {
|
|
108
|
-
return
|
|
77
|
+
return optionValue === currentValue;
|
|
109
78
|
}
|
|
110
79
|
|
|
111
80
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
@@ -119,7 +88,7 @@ function CustomSelect(_ref) {
|
|
|
119
88
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
120
89
|
className: "my-select__icon",
|
|
121
90
|
children: icon
|
|
122
|
-
}), title,
|
|
91
|
+
}), title, /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.SvgIcon, {
|
|
123
92
|
className: "my-select__arrowdown",
|
|
124
93
|
component: _KeyboardArrowDown.default,
|
|
125
94
|
fontSize: "small"
|
|
@@ -152,13 +121,10 @@ function CustomSelect(_ref) {
|
|
|
152
121
|
return itemRender(option);
|
|
153
122
|
}
|
|
154
123
|
|
|
155
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
124
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
|
|
156
125
|
onClick: () => toggle(option),
|
|
157
126
|
className: ['my-select__option', containsValue(option.value) ? 'my-select__option--active' : ''].join(' '),
|
|
158
|
-
children:
|
|
159
|
-
component: _Check.default,
|
|
160
|
-
className: ['my-select__option__icon', containsValue(option.value) ? 'my-select__option__icon--active' : ''].join(' ')
|
|
161
|
-
}), option.name]
|
|
127
|
+
children: option.name
|
|
162
128
|
}, option.value);
|
|
163
129
|
})]
|
|
164
130
|
})
|
|
@@ -172,11 +138,7 @@ function CustomSelect(_ref) {
|
|
|
172
138
|
|
|
173
139
|
CustomSelect.propTypes = {
|
|
174
140
|
options: _propTypes.default.array.isRequired,
|
|
175
|
-
multiple: _propTypes.default.bool,
|
|
176
141
|
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.array]),
|
|
177
|
-
onShow: _propTypes.default.func,
|
|
178
|
-
onClose: _propTypes.default.func,
|
|
179
|
-
onInput: _propTypes.default.func,
|
|
180
142
|
onChange: _propTypes.default.func,
|
|
181
143
|
itemRender: _propTypes.default.func,
|
|
182
144
|
title: _propTypes.default.string.isRequired,
|
|
@@ -184,14 +146,10 @@ CustomSelect.propTypes = {
|
|
|
184
146
|
prepend: _propTypes.default.any
|
|
185
147
|
};
|
|
186
148
|
CustomSelect.defaultProps = {
|
|
187
|
-
multiple: false,
|
|
188
149
|
value: null,
|
|
189
150
|
icon: null,
|
|
190
151
|
prepend: null,
|
|
191
152
|
itemRender: null,
|
|
192
|
-
onShow: () => {},
|
|
193
|
-
onClose: () => {},
|
|
194
|
-
onInput: () => {},
|
|
195
153
|
onChange: () => {}
|
|
196
154
|
};
|
|
197
155
|
const StyledButton = (0, _styledComponents.default)(_button.default).withConfig({
|
package/lib/contexts/filter.js
CHANGED
|
@@ -99,7 +99,8 @@ function FilterProvider(_ref) {
|
|
|
99
99
|
currentPage: 1,
|
|
100
100
|
pageSize: (0, _utils.isMobileScreen)() ? 10 : 18,
|
|
101
101
|
defaultCurrentPage: 1
|
|
102
|
-
});
|
|
102
|
+
}); // TODO: 这里如果用 useMemo 包裹,滚动分页会异常
|
|
103
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
103
104
|
|
|
104
105
|
const finalFilters = _objectSpread({
|
|
105
106
|
sortBy: 'popularity',
|
|
@@ -113,7 +114,7 @@ function FilterProvider(_ref) {
|
|
|
113
114
|
return !hasDeveloperFilter ? {
|
|
114
115
|
data: allCategories
|
|
115
116
|
} : (0, _utils.getCategoriesByAuthor)(allBlocklets, finalFilters.developer);
|
|
116
|
-
}, [hasDeveloperFilter, allCategories, allBlocklets]);
|
|
117
|
+
}, [hasDeveloperFilter, allCategories, allBlocklets, finalFilters.developer]);
|
|
117
118
|
const blockletList = (0, _react.useMemo)(() => {
|
|
118
119
|
var _finalFilters$keyword;
|
|
119
120
|
|
|
@@ -158,7 +159,7 @@ function FilterProvider(_ref) {
|
|
|
158
159
|
blocklets = extraFilter(blocklets); // 排序
|
|
159
160
|
|
|
160
161
|
return (0, _orderBy.default)(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
|
|
161
|
-
}, [allBlocklets, finalFilters]);
|
|
162
|
+
}, [allBlocklets, finalFilters, selectedCategory, extraFilter]);
|
|
162
163
|
const finalBlockletList = (0, _react.useMemo)(() => {
|
|
163
164
|
// 前端分页 currentPage 当前页数 pageSize 每页条数
|
|
164
165
|
return blockletList.slice((paginateState.defaultCurrentPage - 1) * paginateState.pageSize, paginateState.currentPage * paginateState.pageSize);
|
|
@@ -281,11 +282,12 @@ function FilterProvider(_ref) {
|
|
|
281
282
|
(0, _react.useEffect)(() => {
|
|
282
283
|
if (!hasDeveloperFilter) {
|
|
283
284
|
fetchCategories();
|
|
284
|
-
}
|
|
285
|
+
} // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
286
|
+
|
|
285
287
|
}, [hasDeveloperFilter]);
|
|
286
288
|
(0, _react.useEffect)(() => {
|
|
287
289
|
fetchBlocklets();
|
|
288
|
-
fetchCategories();
|
|
290
|
+
fetchCategories(); // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
289
291
|
}, [endpoint]);
|
|
290
292
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Provider, {
|
|
291
293
|
value: filterStore,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/list",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.46",
|
|
4
4
|
"description": "Common ux components of blocklet",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"react": ">=18.1.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@arcblock/ux": "^2.1.
|
|
41
|
+
"@arcblock/ux": "^2.1.38",
|
|
42
42
|
"@emotion/react": "^11.9.0",
|
|
43
43
|
"@emotion/styled": "^11.8.1",
|
|
44
44
|
"@mui/icons-material": "^5.6.2",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"eslint": "^8.16.0",
|
|
65
65
|
"prettier": "^2.6.2"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "caf5f978210ea33249edd11182d5b1898ac2b732"
|
|
68
68
|
}
|
|
@@ -1,74 +1,41 @@
|
|
|
1
1
|
/* eslint-disable no-unused-expressions */
|
|
2
|
-
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import useTheme from '@mui/styles/useTheme';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { ClickAwayListener, Grow, MenuItem, MenuList, Paper, Popper, SvgIcon, useMediaQuery } from '@mui/material';
|
|
7
|
-
import CheckIcon from '@mui/icons-material/Check';
|
|
8
7
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
|
|
9
|
-
import cloneDeep from 'lodash/cloneDeep';
|
|
10
8
|
import isEmpty from 'lodash/isEmpty';
|
|
11
|
-
import isEqual from 'lodash/isEqual';
|
|
12
9
|
|
|
13
10
|
import Button from './button';
|
|
14
11
|
|
|
15
|
-
function CustomSelect({
|
|
16
|
-
title,
|
|
17
|
-
value,
|
|
18
|
-
icon,
|
|
19
|
-
prepend,
|
|
20
|
-
options,
|
|
21
|
-
multiple,
|
|
22
|
-
onClose,
|
|
23
|
-
onShow,
|
|
24
|
-
onChange,
|
|
25
|
-
onInput,
|
|
26
|
-
itemRender,
|
|
27
|
-
...buttonProps
|
|
28
|
-
}) {
|
|
12
|
+
function CustomSelect({ title, value, icon, prepend, options, onChange, itemRender, ...buttonProps }) {
|
|
29
13
|
const anchorRef = useRef(null);
|
|
30
14
|
const theme = useTheme();
|
|
31
15
|
const [open, setOpen] = useState(false);
|
|
32
|
-
|
|
33
|
-
const [currentValue, setCurrentValue] = useState(value !== null ? value : multiple ? [] : '');
|
|
16
|
+
const [currentValue, setCurrentValue] = useState(value !== null ? value : '');
|
|
34
17
|
const isSm = useMediaQuery(theme.breakpoints.down('sm'));
|
|
35
18
|
|
|
36
19
|
useEffect(() => {
|
|
37
|
-
|
|
38
|
-
setCurrentValue(value !== null ? value : multiple ? [] : '');
|
|
20
|
+
setCurrentValue(value !== null ? value : '');
|
|
39
21
|
}, [value]);
|
|
40
22
|
|
|
41
|
-
|
|
42
|
-
isEqual(value, currentValue) || onInput(currentValue);
|
|
43
|
-
onClose();
|
|
23
|
+
const closeMenu = useCallback(() => {
|
|
44
24
|
setOpen(false);
|
|
45
|
-
}
|
|
46
|
-
|
|
25
|
+
}, []);
|
|
26
|
+
const openMenu = useCallback(() => {
|
|
47
27
|
setOpen(true);
|
|
48
|
-
|
|
49
|
-
}
|
|
28
|
+
}, []);
|
|
50
29
|
|
|
51
30
|
function toggle(option) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
copyValue.splice(index, 1);
|
|
57
|
-
} else {
|
|
58
|
-
copyValue.push(option.value);
|
|
59
|
-
}
|
|
60
|
-
setCurrentValue(copyValue);
|
|
61
|
-
onChange(copyValue);
|
|
62
|
-
} else {
|
|
63
|
-
setCurrentValue(option.value);
|
|
64
|
-
onChange(option.value);
|
|
65
|
-
if (isSm) {
|
|
66
|
-
closeMenu();
|
|
67
|
-
}
|
|
31
|
+
setCurrentValue(option.value);
|
|
32
|
+
onChange(option.value);
|
|
33
|
+
if (isSm) {
|
|
34
|
+
closeMenu();
|
|
68
35
|
}
|
|
69
36
|
}
|
|
70
37
|
function containsValue(optionValue) {
|
|
71
|
-
return
|
|
38
|
+
return optionValue === currentValue;
|
|
72
39
|
}
|
|
73
40
|
|
|
74
41
|
return (
|
|
@@ -82,7 +49,6 @@ function CustomSelect({
|
|
|
82
49
|
{...buttonProps}>
|
|
83
50
|
<div className="my-select__icon">{icon}</div>
|
|
84
51
|
{title}
|
|
85
|
-
{multiple && currentValue.length > 1 && ` (${currentValue.length})`}
|
|
86
52
|
<SvgIcon className="my-select__arrowdown" component={KeyboardArrowDownIcon} fontSize="small" />
|
|
87
53
|
</StyledButton>
|
|
88
54
|
<Popper open={open} anchorEl={anchorRef.current} transition style={{ zIndex: '9999' }}>
|
|
@@ -106,15 +72,6 @@ function CustomSelect({
|
|
|
106
72
|
'my-select__option',
|
|
107
73
|
containsValue(option.value) ? 'my-select__option--active' : '',
|
|
108
74
|
].join(' ')}>
|
|
109
|
-
{multiple && (
|
|
110
|
-
<SvgIcon
|
|
111
|
-
component={CheckIcon}
|
|
112
|
-
className={[
|
|
113
|
-
'my-select__option__icon',
|
|
114
|
-
containsValue(option.value) ? 'my-select__option__icon--active' : '',
|
|
115
|
-
].join(' ')}
|
|
116
|
-
/>
|
|
117
|
-
)}
|
|
118
75
|
{option.name}
|
|
119
76
|
</MenuItem>
|
|
120
77
|
);
|
|
@@ -131,11 +88,7 @@ function CustomSelect({
|
|
|
131
88
|
|
|
132
89
|
CustomSelect.propTypes = {
|
|
133
90
|
options: PropTypes.array.isRequired,
|
|
134
|
-
multiple: PropTypes.bool,
|
|
135
91
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array]),
|
|
136
|
-
onShow: PropTypes.func,
|
|
137
|
-
onClose: PropTypes.func,
|
|
138
|
-
onInput: PropTypes.func,
|
|
139
92
|
onChange: PropTypes.func,
|
|
140
93
|
itemRender: PropTypes.func,
|
|
141
94
|
title: PropTypes.string.isRequired,
|
|
@@ -143,14 +96,10 @@ CustomSelect.propTypes = {
|
|
|
143
96
|
prepend: PropTypes.any,
|
|
144
97
|
};
|
|
145
98
|
CustomSelect.defaultProps = {
|
|
146
|
-
multiple: false,
|
|
147
99
|
value: null,
|
|
148
100
|
icon: null,
|
|
149
101
|
prepend: null,
|
|
150
102
|
itemRender: null,
|
|
151
|
-
onShow: () => {},
|
|
152
|
-
onClose: () => {},
|
|
153
|
-
onInput: () => {},
|
|
154
103
|
onChange: () => {},
|
|
155
104
|
};
|
|
156
105
|
|
package/src/contexts/filter.js
CHANGED
|
@@ -55,13 +55,16 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
const paginateState = useReactive({ currentPage: 1, pageSize: isMobileScreen() ? 10 : 18, defaultCurrentPage: 1 });
|
|
58
|
+
// TODO: 这里如果用 useMemo 包裹,滚动分页会异常
|
|
59
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
58
60
|
const finalFilters = { sortBy: 'popularity', sortDirection: 'desc', ...filters };
|
|
61
|
+
|
|
59
62
|
const selectedCategory = finalFilters.category;
|
|
60
63
|
const hasDeveloperFilter = !!finalFilters.developer;
|
|
61
64
|
const categoryState = useMemo(() => {
|
|
62
65
|
// 当按作者过滤时,需要从所有blocklets中找出属于作者的分类
|
|
63
66
|
return !hasDeveloperFilter ? { data: allCategories } : getCategoriesByAuthor(allBlocklets, finalFilters.developer);
|
|
64
|
-
}, [hasDeveloperFilter, allCategories, allBlocklets]);
|
|
67
|
+
}, [hasDeveloperFilter, allCategories, allBlocklets, finalFilters.developer]);
|
|
65
68
|
|
|
66
69
|
const blockletList = useMemo(() => {
|
|
67
70
|
const sortByName = (x) => x?.title?.toLocaleLowerCase() || x?.name?.toLocaleLowerCase(); // 按名称排序
|
|
@@ -95,7 +98,7 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
95
98
|
blocklets = extraFilter(blocklets);
|
|
96
99
|
// 排序
|
|
97
100
|
return orderBy(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
|
|
98
|
-
}, [allBlocklets, finalFilters]);
|
|
101
|
+
}, [allBlocklets, finalFilters, selectedCategory, extraFilter]);
|
|
99
102
|
|
|
100
103
|
const finalBlockletList = useMemo(() => {
|
|
101
104
|
// 前端分页 currentPage 当前页数 pageSize 每页条数
|
|
@@ -197,11 +200,13 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
|
|
|
197
200
|
if (!hasDeveloperFilter) {
|
|
198
201
|
fetchCategories();
|
|
199
202
|
}
|
|
203
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
200
204
|
}, [hasDeveloperFilter]);
|
|
201
205
|
|
|
202
206
|
useEffect(() => {
|
|
203
207
|
fetchBlocklets();
|
|
204
208
|
fetchCategories();
|
|
209
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
205
210
|
}, [endpoint]);
|
|
206
211
|
|
|
207
212
|
return <Provider value={filterStore}>{children}</Provider>;
|