@blocklet/list 0.8.43 → 0.8.44

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", "multiple", "onClose", "onShow", "onChange", "onInput", "itemRender"];
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); // eslint-disable-next-line no-nested-ternary
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
- // eslint-disable-next-line no-nested-ternary
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
- onShow();
82
- }
65
+ }, []);
83
66
 
84
67
  function toggle(option) {
85
- if (multiple) {
86
- const copyValue = (0, _cloneDeep.default)(currentValue);
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
- setCurrentValue(copyValue);
96
- onChange(copyValue);
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 multiple ? currentValue.includes(optionValue) : optionValue === currentValue;
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, multiple && currentValue.length > 1 && " (".concat(currentValue.length, ")"), /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.SvgIcon, {
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.jsxs)(_material.MenuItem, {
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: [multiple && /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.SvgIcon, {
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({
@@ -100,12 +100,12 @@ function FilterProvider(_ref) {
100
100
  pageSize: (0, _utils.isMobileScreen)() ? 10 : 18,
101
101
  defaultCurrentPage: 1
102
102
  });
103
-
104
- const finalFilters = _objectSpread({
105
- sortBy: 'popularity',
106
- sortDirection: 'desc'
107
- }, filters);
108
-
103
+ const finalFilters = (0, _react.useMemo)(() => {
104
+ return _objectSpread({
105
+ sortBy: 'popularity',
106
+ sortDirection: 'desc'
107
+ }, filters);
108
+ }, [filters]);
109
109
  const selectedCategory = finalFilters.category;
110
110
  const hasDeveloperFilter = !!finalFilters.developer;
111
111
  const categoryState = (0, _react.useMemo)(() => {
@@ -113,7 +113,7 @@ function FilterProvider(_ref) {
113
113
  return !hasDeveloperFilter ? {
114
114
  data: allCategories
115
115
  } : (0, _utils.getCategoriesByAuthor)(allBlocklets, finalFilters.developer);
116
- }, [hasDeveloperFilter, allCategories, allBlocklets]);
116
+ }, [hasDeveloperFilter, allCategories, allBlocklets, finalFilters.developer]);
117
117
  const blockletList = (0, _react.useMemo)(() => {
118
118
  var _finalFilters$keyword;
119
119
 
@@ -158,7 +158,7 @@ function FilterProvider(_ref) {
158
158
  blocklets = extraFilter(blocklets); // 排序
159
159
 
160
160
  return (0, _orderBy.default)(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
161
- }, [allBlocklets, finalFilters]);
161
+ }, [allBlocklets, finalFilters, selectedCategory, extraFilter]);
162
162
  const finalBlockletList = (0, _react.useMemo)(() => {
163
163
  // 前端分页 currentPage 当前页数 pageSize 每页条数
164
164
  return blockletList.slice((paginateState.defaultCurrentPage - 1) * paginateState.pageSize, paginateState.currentPage * paginateState.pageSize);
@@ -281,11 +281,12 @@ function FilterProvider(_ref) {
281
281
  (0, _react.useEffect)(() => {
282
282
  if (!hasDeveloperFilter) {
283
283
  fetchCategories();
284
- }
284
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
285
+
285
286
  }, [hasDeveloperFilter]);
286
287
  (0, _react.useEffect)(() => {
287
288
  fetchBlocklets();
288
- fetchCategories();
289
+ fetchCategories(); // eslint-disable-next-line react-hooks/exhaustive-deps
289
290
  }, [endpoint]);
290
291
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(Provider, {
291
292
  value: filterStore,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/list",
3
- "version": "0.8.43",
3
+ "version": "0.8.44",
4
4
  "description": "Common ux components of blocklet",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -64,5 +64,5 @@
64
64
  "eslint": "^8.16.0",
65
65
  "prettier": "^2.6.2"
66
66
  },
67
- "gitHead": "092de42814fb2c3930edba71145f4e7a634e8cd0"
67
+ "gitHead": "b4341c37c377e1dfc9f8b3e99be80dd3f30493d4"
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
- // eslint-disable-next-line no-nested-ternary
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
- // eslint-disable-next-line no-nested-ternary
38
- setCurrentValue(value !== null ? value : multiple ? [] : '');
20
+ setCurrentValue(value !== null ? value : '');
39
21
  }, [value]);
40
22
 
41
- function closeMenu() {
42
- isEqual(value, currentValue) || onInput(currentValue);
43
- onClose();
23
+ const closeMenu = useCallback(() => {
44
24
  setOpen(false);
45
- }
46
- function openMenu() {
25
+ }, []);
26
+ const openMenu = useCallback(() => {
47
27
  setOpen(true);
48
- onShow();
49
- }
28
+ }, []);
50
29
 
51
30
  function toggle(option) {
52
- if (multiple) {
53
- const copyValue = cloneDeep(currentValue);
54
- const index = copyValue.indexOf(option.value);
55
- if (index >= 0) {
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 multiple ? currentValue.includes(optionValue) : optionValue === currentValue;
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
 
@@ -55,13 +55,15 @@ 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
- const finalFilters = { sortBy: 'popularity', sortDirection: 'desc', ...filters };
58
+ const finalFilters = useMemo(() => {
59
+ return { sortBy: 'popularity', sortDirection: 'desc', ...filters };
60
+ }, [filters]);
59
61
  const selectedCategory = finalFilters.category;
60
62
  const hasDeveloperFilter = !!finalFilters.developer;
61
63
  const categoryState = useMemo(() => {
62
64
  // 当按作者过滤时,需要从所有blocklets中找出属于作者的分类
63
65
  return !hasDeveloperFilter ? { data: allCategories } : getCategoriesByAuthor(allBlocklets, finalFilters.developer);
64
- }, [hasDeveloperFilter, allCategories, allBlocklets]);
66
+ }, [hasDeveloperFilter, allCategories, allBlocklets, finalFilters.developer]);
65
67
 
66
68
  const blockletList = useMemo(() => {
67
69
  const sortByName = (x) => x?.title?.toLocaleLowerCase() || x?.name?.toLocaleLowerCase(); // 按名称排序
@@ -95,7 +97,7 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
95
97
  blocklets = extraFilter(blocklets);
96
98
  // 排序
97
99
  return orderBy(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
98
- }, [allBlocklets, finalFilters]);
100
+ }, [allBlocklets, finalFilters, selectedCategory, extraFilter]);
99
101
 
100
102
  const finalBlockletList = useMemo(() => {
101
103
  // 前端分页 currentPage 当前页数 pageSize 每页条数
@@ -197,11 +199,13 @@ function FilterProvider({ filters, children, endpoint, locale, blockletRender, o
197
199
  if (!hasDeveloperFilter) {
198
200
  fetchCategories();
199
201
  }
202
+ // eslint-disable-next-line react-hooks/exhaustive-deps
200
203
  }, [hasDeveloperFilter]);
201
204
 
202
205
  useEffect(() => {
203
206
  fetchBlocklets();
204
207
  fetchCategories();
208
+ // eslint-disable-next-line react-hooks/exhaustive-deps
205
209
  }, [endpoint]);
206
210
 
207
211
  return <Provider value={filterStore}>{children}</Provider>;