@blocklet/list 0.10.26 → 0.10.28
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/lib/base.js +4 -2
- package/lib/components/autocomplete/index.js +48 -33
- package/lib/contexts/filter.js +3 -1
- package/lib/index.js +1 -1
- package/lib/libs/prop-types.js +2 -0
- package/package.json +2 -2
- package/src/base.js +2 -2
- package/src/components/autocomplete/index.js +42 -51
- package/src/contexts/filter.js +2 -0
- package/src/index.js +4 -1
- package/src/libs/prop-types.js +2 -0
- package/lib/components/autocomplete/item.js +0 -133
- package/src/components/autocomplete/item.js +0 -120
package/lib/base.js
CHANGED
|
@@ -53,7 +53,8 @@ function ListBase() {
|
|
|
53
53
|
handleSearchSelect,
|
|
54
54
|
t,
|
|
55
55
|
getCategoryLocale,
|
|
56
|
-
priceOptions
|
|
56
|
+
priceOptions,
|
|
57
|
+
wrapChildren
|
|
57
58
|
} = (0, _filter.useFilterContext)();
|
|
58
59
|
const sortOptions = (0, _utils.getSortOptions)(t);
|
|
59
60
|
const sortLocale = ((_sortOptions$find = sortOptions.find(f => f.value === filters.sortBy)) === null || _sortOptions$find === void 0 ? void 0 : _sortOptions$find.name) || t('sort.sort');
|
|
@@ -73,7 +74,8 @@ function ListBase() {
|
|
|
73
74
|
display: "flex",
|
|
74
75
|
alignItems: "center",
|
|
75
76
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_autocomplete.default, {
|
|
76
|
-
onSelect: handleSearchSelect
|
|
77
|
+
onSelect: handleSearchSelect,
|
|
78
|
+
wrapChildren: wrapChildren
|
|
77
79
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Box, {
|
|
78
80
|
mt: 0,
|
|
79
81
|
ml: "16px",
|
|
@@ -15,8 +15,6 @@ var _autocompleteJs = require("@algolia/autocomplete-js");
|
|
|
15
15
|
|
|
16
16
|
var _reactHotkeysHook = require("react-hotkeys-hook");
|
|
17
17
|
|
|
18
|
-
var _styles = require("@mui/material/styles");
|
|
19
|
-
|
|
20
18
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
21
19
|
|
|
22
20
|
var _constant = _interopRequireDefault(require("../../libs/constant"));
|
|
@@ -25,10 +23,10 @@ var _utils = require("../../libs/utils");
|
|
|
25
23
|
|
|
26
24
|
var _filter = require("../../contexts/filter");
|
|
27
25
|
|
|
28
|
-
var _item = _interopRequireDefault(require("./item"));
|
|
29
|
-
|
|
30
26
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
31
27
|
|
|
28
|
+
const _excluded = ["query", "state"];
|
|
29
|
+
|
|
32
30
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
31
|
|
|
34
32
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -37,22 +35,28 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
37
35
|
|
|
38
36
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
39
37
|
|
|
38
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
39
|
+
|
|
40
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
41
|
+
|
|
40
42
|
function Autocomplete(_ref) {
|
|
41
43
|
let {
|
|
42
|
-
onSelect
|
|
44
|
+
onSelect,
|
|
45
|
+
wrapChildren
|
|
43
46
|
} = _ref;
|
|
44
47
|
const containerRef = (0, _react.useRef)(null);
|
|
45
48
|
const panelRootRef = (0, _react.useRef)(null);
|
|
46
49
|
const rootRef = (0, _react.useRef)(null);
|
|
47
50
|
const {
|
|
48
51
|
storeApi,
|
|
52
|
+
blockletRender,
|
|
49
53
|
filters,
|
|
50
54
|
endpoint,
|
|
51
55
|
handleKeyword,
|
|
52
56
|
t
|
|
53
57
|
} = (0, _filter.useFilterContext)();
|
|
54
|
-
|
|
55
|
-
const getBlocklets =
|
|
58
|
+
|
|
59
|
+
const getBlocklets = async params => {
|
|
56
60
|
const {
|
|
57
61
|
data
|
|
58
62
|
} = await storeApi.get(_constant.default.blockletsPath, {
|
|
@@ -68,10 +72,12 @@ function Autocomplete(_ref) {
|
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
return blocklets;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const onSubmit = autocompleteState => {
|
|
78
|
+
handleKeyword(autocompleteState.state.query);
|
|
79
|
+
autocompleteState.setIsOpen(false);
|
|
80
|
+
};
|
|
75
81
|
|
|
76
82
|
const setFocus = () => {
|
|
77
83
|
if (containerRef.current) {
|
|
@@ -86,24 +92,26 @@ function Autocomplete(_ref) {
|
|
|
86
92
|
}
|
|
87
93
|
};
|
|
88
94
|
|
|
89
|
-
const onReset =
|
|
95
|
+
const onReset = autocompleteState => {
|
|
90
96
|
autocompleteState.setIsOpen(false);
|
|
91
97
|
setFocus();
|
|
92
|
-
}
|
|
93
|
-
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const onStateChange = _ref2 => {
|
|
94
101
|
let {
|
|
95
102
|
prevState,
|
|
96
103
|
state
|
|
97
104
|
} = _ref2;
|
|
98
105
|
|
|
99
|
-
//
|
|
106
|
+
// 当搜索框中的值清空时, 更新页面中的搜索结果
|
|
100
107
|
if (prevState.query !== state.query) {
|
|
101
108
|
if (!state.query) {
|
|
102
109
|
handleKeyword();
|
|
103
110
|
}
|
|
104
111
|
}
|
|
105
|
-
}
|
|
106
|
-
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
(0, _reactHotkeysHook.useHotkeys)('ctrl + k, command + k', e => {
|
|
107
115
|
e.stopPropagation();
|
|
108
116
|
e.preventDefault();
|
|
109
117
|
setFocus();
|
|
@@ -140,10 +148,11 @@ function Autocomplete(_ref) {
|
|
|
140
148
|
panelRootRef.current = (0, _client.createRoot)(root);
|
|
141
149
|
}
|
|
142
150
|
|
|
143
|
-
panelRootRef.current.render(children);
|
|
151
|
+
panelRootRef.current.render(wrapChildren(children));
|
|
144
152
|
},
|
|
145
153
|
|
|
146
|
-
autoFocus:
|
|
154
|
+
autoFocus: true,
|
|
155
|
+
openOnFocus: false,
|
|
147
156
|
classNames: {
|
|
148
157
|
panel: 'bl-autocomplete-panel',
|
|
149
158
|
label: 'bl-autocomplete-label',
|
|
@@ -168,8 +177,10 @@ function Autocomplete(_ref) {
|
|
|
168
177
|
|
|
169
178
|
getSources(_ref4) {
|
|
170
179
|
let {
|
|
171
|
-
query
|
|
172
|
-
|
|
180
|
+
query,
|
|
181
|
+
state
|
|
182
|
+
} = _ref4,
|
|
183
|
+
setters = _objectWithoutProperties(_ref4, _excluded);
|
|
173
184
|
|
|
174
185
|
const params = _objectSpread(_objectSpread({}, filters), {}, {
|
|
175
186
|
sortBy: _constant.default[filters.sortBy],
|
|
@@ -201,13 +212,19 @@ function Autocomplete(_ref) {
|
|
|
201
212
|
// 选中或者点击自动完成列表中的 item 时触发
|
|
202
213
|
onSelect(_ref6) {
|
|
203
214
|
let {
|
|
215
|
+
event,
|
|
204
216
|
item
|
|
205
217
|
} = _ref6;
|
|
206
218
|
|
|
207
219
|
if (item.type === 'more-result') {
|
|
220
|
+
setters.setIsOpen(false);
|
|
208
221
|
return handleKeyword(query);
|
|
209
222
|
}
|
|
210
223
|
|
|
224
|
+
if (event.type === 'keydown') {
|
|
225
|
+
return handleKeyword(item.title);
|
|
226
|
+
}
|
|
227
|
+
|
|
211
228
|
return onSelect({
|
|
212
229
|
blocklet: item,
|
|
213
230
|
detailUrl: (0, _urlJoin.default)(endpoint, "/blocklets/".concat(item.did)),
|
|
@@ -220,7 +237,6 @@ function Autocomplete(_ref) {
|
|
|
220
237
|
let {
|
|
221
238
|
item
|
|
222
239
|
} = _ref7;
|
|
223
|
-
const logoUrl = item.logo ? (0, _urlJoin.default)(endpoint, 'assets', item.did, item.logo) : null;
|
|
224
240
|
|
|
225
241
|
if (item.type === 'more-result') {
|
|
226
242
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
@@ -231,14 +247,9 @@ function Autocomplete(_ref) {
|
|
|
231
247
|
});
|
|
232
248
|
}
|
|
233
249
|
|
|
234
|
-
return
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
item: item,
|
|
238
|
-
did: item.did,
|
|
239
|
-
description: item.description,
|
|
240
|
-
cover: logoUrl
|
|
241
|
-
})
|
|
250
|
+
return blockletRender({
|
|
251
|
+
blocklet: item,
|
|
252
|
+
autocompleteSetters: setters
|
|
242
253
|
});
|
|
243
254
|
},
|
|
244
255
|
|
|
@@ -253,8 +264,8 @@ function Autocomplete(_ref) {
|
|
|
253
264
|
});
|
|
254
265
|
return () => {
|
|
255
266
|
search.destroy();
|
|
256
|
-
};
|
|
257
|
-
}, [
|
|
267
|
+
}; // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
268
|
+
}, [filters, blockletRender]);
|
|
258
269
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
259
270
|
className: "bl-search-container",
|
|
260
271
|
ref: containerRef
|
|
@@ -262,5 +273,9 @@ function Autocomplete(_ref) {
|
|
|
262
273
|
}
|
|
263
274
|
|
|
264
275
|
Autocomplete.propTypes = {
|
|
265
|
-
onSelect: _propTypes.default.func.isRequired
|
|
276
|
+
onSelect: _propTypes.default.func.isRequired,
|
|
277
|
+
wrapChildren: _propTypes.default.func
|
|
278
|
+
};
|
|
279
|
+
Autocomplete.defaultProps = {
|
|
280
|
+
wrapChildren: children => children
|
|
266
281
|
};
|
package/lib/contexts/filter.js
CHANGED
|
@@ -51,7 +51,8 @@ function FilterProvider(_ref) {
|
|
|
51
51
|
blockletRender,
|
|
52
52
|
onFilterChange,
|
|
53
53
|
onSearchSelect,
|
|
54
|
-
extraFilter
|
|
54
|
+
extraFilter,
|
|
55
|
+
wrapChildren
|
|
55
56
|
} = _ref;
|
|
56
57
|
const storeApi = (0, _react.useMemo)(() => {
|
|
57
58
|
return _axios.default.create({
|
|
@@ -147,6 +148,7 @@ function FilterProvider(_ref) {
|
|
|
147
148
|
},
|
|
148
149
|
endpoint,
|
|
149
150
|
blockletList,
|
|
151
|
+
wrapChildren,
|
|
150
152
|
t: translate,
|
|
151
153
|
filters: finalFilters,
|
|
152
154
|
selectedCategory,
|
package/lib/index.js
CHANGED
|
@@ -37,7 +37,7 @@ function BlockletList(props) {
|
|
|
37
37
|
const muiTheme = (0, _styles.useTheme)();
|
|
38
38
|
const primaryColor = (0, _utils.toColorRgb)(muiTheme.palette.primary.main);
|
|
39
39
|
const globalStyles = {
|
|
40
|
-
autocomplete: theme => (0, _react.css)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n :root {\n --aa-detached-media-query: (max-width: ", "px) !important;\n --aa-detached-modal-media-query: (min-width: ", "px) !important;\n --aa-detached-modal-max-width: ", "px !important;\n --aa-selected-color-rgb: ", ", ", ", ", " !important;\n --aa-primary-color-rgb: ", ", ", ", ", " !important;\n --aa-input-background-color-rgb: 250, 250, 250 !important;\n }\n .bl-autocomplete-panel {\n z-index: ", "
|
|
40
|
+
autocomplete: theme => (0, _react.css)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n :root {\n --aa-detached-media-query: (max-width: ", "px) !important;\n --aa-detached-modal-media-query: (min-width: ", "px) !important;\n --aa-detached-modal-max-width: ", "px !important;\n --aa-selected-color-rgb: ", ", ", ", ", " !important;\n --aa-primary-color-rgb: ", ", ", ", ", " !important;\n --aa-input-background-color-rgb: 250, 250, 250 !important;\n }\n .bl-autocomplete-panel {\n z-index: ", ";\n }\n .bl-autocomplete-label {\n .aa-SubmitIcon {\n color: ", " !important;\n }\n }\n .bl-autocomplete-form {\n border: 1px solid #fff !important;\n &:focus-within {\n box-shadow: none !important;\n border: 1px solid rgba(0, 0, 0, 0.12) !important;\n }\n }\n .aa-DetachedSearchButton {\n border: none !important;\n &:focus-within {\n box-shadow: none !important;\n }\n .aa-SubmitIcon {\n color: ", " !important;\n }\n }\n .aa-Panel .arcblock-blocklet button {\n border: 1px solid rgba(", ", ", ", ", ", 0.5);\n }\n "])), theme.breakpoints.values.md, theme.breakpoints.values.md, theme.breakpoints.values.md, primaryColor.r, primaryColor.g, primaryColor.b, primaryColor.r, primaryColor.g, primaryColor.b, theme.zIndex.modal, theme.palette.grey[500], theme.palette.grey[500], primaryColor.r, primaryColor.g, primaryColor.b)
|
|
41
41
|
};
|
|
42
42
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_filter.FilterProvider, _objectSpread(_objectSpread({}, props), {}, {
|
|
43
43
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_react.Global, {
|
package/lib/libs/prop-types.js
CHANGED
|
@@ -18,6 +18,7 @@ const propTypes = {
|
|
|
18
18
|
category: _propTypes.default.string,
|
|
19
19
|
developer: _propTypes.default.string
|
|
20
20
|
}),
|
|
21
|
+
wrapChildren: _propTypes.default.func,
|
|
21
22
|
extraFilter: _propTypes.default.func,
|
|
22
23
|
endpoint: _propTypes.default.string.isRequired,
|
|
23
24
|
blockletRender: _propTypes.default.func.isRequired,
|
|
@@ -36,6 +37,7 @@ const defaultProps = {
|
|
|
36
37
|
} = _ref;
|
|
37
38
|
window.location.href = detailUrl;
|
|
38
39
|
},
|
|
40
|
+
wrapChildren: children => children,
|
|
39
41
|
extraFilter: list => list
|
|
40
42
|
};
|
|
41
43
|
exports.defaultProps = defaultProps;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/list",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.28",
|
|
4
4
|
"description": "Common ux components of blocklet",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"eslint": "^8.22.0",
|
|
72
72
|
"prettier": "^2.7.1"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "0176029eaadc440b69e9255d83873bbcbae1edcd"
|
|
75
75
|
}
|
package/src/base.js
CHANGED
|
@@ -26,12 +26,12 @@ function ListBase() {
|
|
|
26
26
|
t,
|
|
27
27
|
getCategoryLocale,
|
|
28
28
|
priceOptions,
|
|
29
|
+
wrapChildren,
|
|
29
30
|
} = useFilterContext();
|
|
30
31
|
const sortOptions = getSortOptions(t);
|
|
31
32
|
const sortLocale = sortOptions.find((f) => f.value === filters.sortBy)?.name || t('sort.sort');
|
|
32
33
|
const categoryLocale = getCategoryLocale(filters.category);
|
|
33
34
|
const priceLocale = priceOptions.find((price) => price.value === filters.price)?.name;
|
|
34
|
-
|
|
35
35
|
return (
|
|
36
36
|
<Box display="flex" alignItems="flex-start" height="100%">
|
|
37
37
|
<Hidden mdDown>
|
|
@@ -40,7 +40,7 @@ function ListBase() {
|
|
|
40
40
|
<StyledMin>
|
|
41
41
|
<FilterContainer>
|
|
42
42
|
<Box className="filter-bar" display="flex" alignItems="center">
|
|
43
|
-
<Autocomplete onSelect={handleSearchSelect} />
|
|
43
|
+
<Autocomplete onSelect={handleSearchSelect} wrapChildren={wrapChildren} />
|
|
44
44
|
<Box mt={0} ml="16px" className="filter-container">
|
|
45
45
|
<Hidden mdUp>
|
|
46
46
|
{/* 小屏幕下类别 */}
|
|
@@ -1,43 +1,34 @@
|
|
|
1
|
-
import { createElement, Fragment, useEffect, useRef
|
|
1
|
+
import { createElement, Fragment, useEffect, useRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { createRoot } from 'react-dom/client';
|
|
4
4
|
import { autocomplete } from '@algolia/autocomplete-js';
|
|
5
5
|
import { useHotkeys } from 'react-hotkeys-hook';
|
|
6
6
|
|
|
7
|
-
import { ThemeProvider as MuiThemeProvider, useTheme } from '@mui/material/styles';
|
|
8
7
|
import joinUrl from 'url-join';
|
|
9
8
|
|
|
10
9
|
import constant from '../../libs/constant';
|
|
11
10
|
import { debounced } from '../../libs/utils';
|
|
12
11
|
import { useFilterContext } from '../../contexts/filter';
|
|
13
|
-
import Blocklet from './item';
|
|
14
12
|
|
|
15
|
-
export default function Autocomplete({ onSelect }) {
|
|
13
|
+
export default function Autocomplete({ onSelect, wrapChildren }) {
|
|
16
14
|
const containerRef = useRef(null);
|
|
17
15
|
const panelRootRef = useRef(null);
|
|
18
16
|
const rootRef = useRef(null);
|
|
19
|
-
const { storeApi, filters, endpoint, handleKeyword, t } = useFilterContext();
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return blocklets;
|
|
31
|
-
},
|
|
32
|
-
[storeApi]
|
|
33
|
-
);
|
|
17
|
+
const { storeApi, blockletRender, filters, endpoint, handleKeyword, t } = useFilterContext();
|
|
18
|
+
const getBlocklets = async (params) => {
|
|
19
|
+
const { data } = await storeApi.get(constant.blockletsPath, { params });
|
|
20
|
+
const blocklets = data.dataList || [];
|
|
21
|
+
// 头部插入的一条 item 用于展示 `点击展开 xx条 结果`,如果没有blocklet 返回,不展示
|
|
22
|
+
if (blocklets.length > 0) {
|
|
23
|
+
blocklets.unshift({ type: 'more-result', total: data.total || 0 });
|
|
24
|
+
}
|
|
25
|
+
return blocklets;
|
|
26
|
+
};
|
|
34
27
|
|
|
35
|
-
const onSubmit =
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
[handleKeyword]
|
|
40
|
-
);
|
|
28
|
+
const onSubmit = (autocompleteState) => {
|
|
29
|
+
handleKeyword(autocompleteState.state.query);
|
|
30
|
+
autocompleteState.setIsOpen(false);
|
|
31
|
+
};
|
|
41
32
|
|
|
42
33
|
const setFocus = () => {
|
|
43
34
|
if (containerRef.current) {
|
|
@@ -51,25 +42,22 @@ export default function Autocomplete({ onSelect }) {
|
|
|
51
42
|
}
|
|
52
43
|
};
|
|
53
44
|
|
|
54
|
-
const onReset =
|
|
45
|
+
const onReset = (autocompleteState) => {
|
|
55
46
|
autocompleteState.setIsOpen(false);
|
|
56
47
|
setFocus();
|
|
57
|
-
}
|
|
48
|
+
};
|
|
58
49
|
|
|
59
|
-
const onStateChange =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
handleKeyword();
|
|
65
|
-
}
|
|
50
|
+
const onStateChange = ({ prevState, state }) => {
|
|
51
|
+
// 当搜索框中的值清空时, 更新页面中的搜索结果
|
|
52
|
+
if (prevState.query !== state.query) {
|
|
53
|
+
if (!state.query) {
|
|
54
|
+
handleKeyword();
|
|
66
55
|
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
70
58
|
|
|
71
59
|
useHotkeys(
|
|
72
|
-
'
|
|
60
|
+
'ctrl + k, command + k',
|
|
73
61
|
(e) => {
|
|
74
62
|
e.stopPropagation();
|
|
75
63
|
e.preventDefault();
|
|
@@ -87,7 +75,6 @@ export default function Autocomplete({ onSelect }) {
|
|
|
87
75
|
if (!containerRef.current) {
|
|
88
76
|
return undefined;
|
|
89
77
|
}
|
|
90
|
-
|
|
91
78
|
const search = autocomplete({
|
|
92
79
|
container: containerRef.current,
|
|
93
80
|
renderer: { createElement, Fragment, render: () => {} },
|
|
@@ -98,10 +85,10 @@ export default function Autocomplete({ onSelect }) {
|
|
|
98
85
|
panelRootRef.current?.unmount();
|
|
99
86
|
panelRootRef.current = createRoot(root);
|
|
100
87
|
}
|
|
101
|
-
|
|
102
|
-
panelRootRef.current.render(children);
|
|
88
|
+
panelRootRef.current.render(wrapChildren(children));
|
|
103
89
|
},
|
|
104
|
-
autoFocus:
|
|
90
|
+
autoFocus: true,
|
|
91
|
+
openOnFocus: false,
|
|
105
92
|
classNames: {
|
|
106
93
|
panel: 'bl-autocomplete-panel',
|
|
107
94
|
label: 'bl-autocomplete-label',
|
|
@@ -120,7 +107,7 @@ export default function Autocomplete({ onSelect }) {
|
|
|
120
107
|
onReset(autocompleteState) {
|
|
121
108
|
onReset(autocompleteState);
|
|
122
109
|
},
|
|
123
|
-
getSources({ query }) {
|
|
110
|
+
getSources({ query, state, ...setters }) {
|
|
124
111
|
const params = {
|
|
125
112
|
...filters,
|
|
126
113
|
sortBy: constant[filters.sortBy],
|
|
@@ -142,10 +129,14 @@ export default function Autocomplete({ onSelect }) {
|
|
|
142
129
|
return item.title;
|
|
143
130
|
},
|
|
144
131
|
// 选中或者点击自动完成列表中的 item 时触发
|
|
145
|
-
onSelect({ item }) {
|
|
132
|
+
onSelect({ event, item }) {
|
|
146
133
|
if (item.type === 'more-result') {
|
|
134
|
+
setters.setIsOpen(false);
|
|
147
135
|
return handleKeyword(query);
|
|
148
136
|
}
|
|
137
|
+
if (event.type === 'keydown') {
|
|
138
|
+
return handleKeyword(item.title);
|
|
139
|
+
}
|
|
149
140
|
return onSelect({
|
|
150
141
|
blocklet: item,
|
|
151
142
|
detailUrl: joinUrl(endpoint, `/blocklets/${item.did}`),
|
|
@@ -154,17 +145,12 @@ export default function Autocomplete({ onSelect }) {
|
|
|
154
145
|
},
|
|
155
146
|
templates: {
|
|
156
147
|
item({ item }) {
|
|
157
|
-
const logoUrl = item.logo ? joinUrl(endpoint, 'assets', item.did, item.logo) : null;
|
|
158
148
|
if (item.type === 'more-result') {
|
|
159
149
|
return (
|
|
160
150
|
<div>{t('autocomplete.expandResult', { name: query, number: item.total.toLocaleString() })}</div>
|
|
161
151
|
);
|
|
162
152
|
}
|
|
163
|
-
return (
|
|
164
|
-
<MuiThemeProvider theme={muiTheme}>
|
|
165
|
-
<Blocklet item={item} did={item.did} description={item.description} cover={logoUrl} />
|
|
166
|
-
</MuiThemeProvider>
|
|
167
|
-
);
|
|
153
|
+
return blockletRender({ blocklet: item, autocompleteSetters: setters });
|
|
168
154
|
},
|
|
169
155
|
noResults() {
|
|
170
156
|
return t('blocklet.noResults');
|
|
@@ -178,11 +164,16 @@ export default function Autocomplete({ onSelect }) {
|
|
|
178
164
|
return () => {
|
|
179
165
|
search.destroy();
|
|
180
166
|
};
|
|
181
|
-
|
|
167
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
168
|
+
}, [filters, blockletRender]);
|
|
182
169
|
|
|
183
170
|
return <div className="bl-search-container" ref={containerRef} />;
|
|
184
171
|
}
|
|
185
172
|
|
|
186
173
|
Autocomplete.propTypes = {
|
|
187
174
|
onSelect: PropTypes.func.isRequired,
|
|
175
|
+
wrapChildren: PropTypes.func,
|
|
176
|
+
};
|
|
177
|
+
Autocomplete.defaultProps = {
|
|
178
|
+
wrapChildren: (children) => children,
|
|
188
179
|
};
|
package/src/contexts/filter.js
CHANGED
|
@@ -20,6 +20,7 @@ function FilterProvider({
|
|
|
20
20
|
onFilterChange,
|
|
21
21
|
onSearchSelect,
|
|
22
22
|
extraFilter,
|
|
23
|
+
wrapChildren,
|
|
23
24
|
}) {
|
|
24
25
|
const storeApi = useMemo(() => {
|
|
25
26
|
return axios.create({
|
|
@@ -107,6 +108,7 @@ function FilterProvider({
|
|
|
107
108
|
loadings: { fetchBlockletsLoading, fetchCategoriesLoading, loadingMore },
|
|
108
109
|
endpoint,
|
|
109
110
|
blockletList,
|
|
111
|
+
wrapChildren,
|
|
110
112
|
t: translate,
|
|
111
113
|
filters: finalFilters,
|
|
112
114
|
selectedCategory,
|
package/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ export default function BlockletList(props) {
|
|
|
22
22
|
--aa-input-background-color-rgb: 250, 250, 250 !important;
|
|
23
23
|
}
|
|
24
24
|
.bl-autocomplete-panel {
|
|
25
|
-
z-index: ${theme.zIndex.modal
|
|
25
|
+
z-index: ${theme.zIndex.modal};
|
|
26
26
|
}
|
|
27
27
|
.bl-autocomplete-label {
|
|
28
28
|
.aa-SubmitIcon {
|
|
@@ -45,6 +45,9 @@ export default function BlockletList(props) {
|
|
|
45
45
|
color: ${theme.palette.grey[500]} !important;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
.aa-Panel .arcblock-blocklet button {
|
|
49
|
+
border: 1px solid rgba(${primaryColor.r}, ${primaryColor.g}, ${primaryColor.b}, 0.5);
|
|
50
|
+
}
|
|
48
51
|
`,
|
|
49
52
|
};
|
|
50
53
|
return (
|
package/src/libs/prop-types.js
CHANGED
|
@@ -9,6 +9,7 @@ const propTypes = {
|
|
|
9
9
|
category: PropTypes.string,
|
|
10
10
|
developer: PropTypes.string,
|
|
11
11
|
}),
|
|
12
|
+
wrapChildren: PropTypes.func,
|
|
12
13
|
extraFilter: PropTypes.func,
|
|
13
14
|
endpoint: PropTypes.string.isRequired,
|
|
14
15
|
blockletRender: PropTypes.func.isRequired,
|
|
@@ -24,6 +25,7 @@ const defaultProps = {
|
|
|
24
25
|
onSearchSelect: ({ detailUrl }) => {
|
|
25
26
|
window.location.href = detailUrl;
|
|
26
27
|
},
|
|
28
|
+
wrapChildren: (children) => children,
|
|
27
29
|
extraFilter: (list) => list,
|
|
28
30
|
};
|
|
29
31
|
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = Blocklet;
|
|
7
|
-
|
|
8
|
-
var _Theme = require("@arcblock/ux/lib/Theme");
|
|
9
|
-
|
|
10
|
-
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
-
|
|
12
|
-
var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
|
|
13
|
-
|
|
14
|
-
var _Img = _interopRequireDefault(require("@arcblock/ux/lib/Img"));
|
|
15
|
-
|
|
16
|
-
var _Avatar = _interopRequireDefault(require("@arcblock/did-connect/lib/Avatar"));
|
|
17
|
-
|
|
18
|
-
var _jsxRuntime = require("react/jsx-runtime");
|
|
19
|
-
|
|
20
|
-
const _excluded = ["cover", "item", "className"];
|
|
21
|
-
|
|
22
|
-
var _templateObject;
|
|
23
|
-
|
|
24
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
-
|
|
26
|
-
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
27
|
-
|
|
28
|
-
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
29
|
-
|
|
30
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
31
|
-
|
|
32
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
33
|
-
|
|
34
|
-
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
35
|
-
|
|
36
|
-
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
37
|
-
|
|
38
|
-
const Div = (0, _Theme.styled)('div')(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n &.arcblock-blocklet {\n padding: ", " ", " 0\n ", ";\n }\n .arcblock-blocklet__content {\n cursor: pointer;\n display: flex;\n }\n .arcblock-blocklet__cover {\n width: 64px;\n height: 64px;\n margin-right: ", ";\n overflow: hidden;\n border-radius: 12px;\n transform: translateZ(0);\n }\n\n .arcblock-blocklet__info {\n flex: 1;\n overflow: hidden;\n border-bottom: 1px solid ", ";\n padding-bottom: ", ";\n }\n .arcblock-blocklet__text {\n height: 57px;\n overflow: hidden;\n }\n /* \u8BBE\u7F6E\u591A\u884C\u6587\u672C\u6EA2\u51FA\u663E\u793A\u7701\u7565\u53F7 \u517C\u5BB9fireFox\u3001safari */\n .arcblock-blocklet__title {\n margin: 0;\n font-size: 16px;\n font-weight: 500;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .arcblock-blocklet__describe {\n margin-top: ", ";\n color: ", ";\n font-size: 14px;\n font-weight: 500;\n line-height: 17px;\n max-height: 34px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n word-break: break-word;\n }\n .ms-highlight {\n color: ", ";\n }\n"])), props => props.theme.spacing(2), props => props.theme.spacing(2), props => props.theme.spacing(2), props => props.theme.spacing(2), props => props.theme.palette.divider, props => props.theme.spacing(2), props => props.theme.spacing(0.5), props => props.theme.palette.grey[600], props => props.theme.palette.primary.main);
|
|
39
|
-
|
|
40
|
-
function Blocklet(_ref) {
|
|
41
|
-
let {
|
|
42
|
-
cover,
|
|
43
|
-
item,
|
|
44
|
-
className
|
|
45
|
-
} = _ref,
|
|
46
|
-
rest = _objectWithoutProperties(_ref, _excluded);
|
|
47
|
-
|
|
48
|
-
const {
|
|
49
|
-
did,
|
|
50
|
-
description,
|
|
51
|
-
title,
|
|
52
|
-
name
|
|
53
|
-
} = item;
|
|
54
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(Div, _objectSpread(_objectSpread({
|
|
55
|
-
className: "".concat(className, " arcblock-blocklet")
|
|
56
|
-
}, rest), {}, {
|
|
57
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
58
|
-
className: "arcblock-blocklet__content",
|
|
59
|
-
children: [cover ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
60
|
-
className: "arcblock-blocklet__cover",
|
|
61
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Img.default, {
|
|
62
|
-
src: cover
|
|
63
|
-
})
|
|
64
|
-
}) : did && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
65
|
-
className: "arcblock-blocklet__cover",
|
|
66
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Avatar.default, {
|
|
67
|
-
did: did,
|
|
68
|
-
size: 64
|
|
69
|
-
})
|
|
70
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
71
|
-
className: "arcblock-blocklet__info",
|
|
72
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
73
|
-
className: "arcblock-blocklet__text",
|
|
74
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
75
|
-
component: "h3",
|
|
76
|
-
variant: "h3",
|
|
77
|
-
className: "arcblock-blocklet__title",
|
|
78
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ShowAttributes, {
|
|
79
|
-
item: item,
|
|
80
|
-
attribute: "title",
|
|
81
|
-
value: title || name
|
|
82
|
-
})
|
|
83
|
-
}), description && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Typography.default, {
|
|
84
|
-
component: "div",
|
|
85
|
-
variant: "body2",
|
|
86
|
-
className: "arcblock-blocklet__describe",
|
|
87
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(ShowAttributes, {
|
|
88
|
-
item: item,
|
|
89
|
-
attribute: "description",
|
|
90
|
-
value: description
|
|
91
|
-
})
|
|
92
|
-
})]
|
|
93
|
-
})
|
|
94
|
-
})]
|
|
95
|
-
})
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
Blocklet.propTypes = {
|
|
100
|
-
cover: _propTypes.default.string,
|
|
101
|
-
className: _propTypes.default.string,
|
|
102
|
-
item: _propTypes.default.object.isRequired
|
|
103
|
-
};
|
|
104
|
-
Blocklet.defaultProps = {
|
|
105
|
-
cover: null,
|
|
106
|
-
className: null
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
function ShowAttributes(_ref2) {
|
|
110
|
-
let {
|
|
111
|
-
item,
|
|
112
|
-
attribute,
|
|
113
|
-
value
|
|
114
|
-
} = _ref2;
|
|
115
|
-
|
|
116
|
-
if (item._formatted) {
|
|
117
|
-
// eslint-disable-next-line react/no-danger
|
|
118
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
119
|
-
"data-cy": "bl-autocomplete-item",
|
|
120
|
-
dangerouslySetInnerHTML: {
|
|
121
|
-
__html: item._formatted[attribute]
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return value;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
ShowAttributes.propTypes = {
|
|
130
|
-
item: _propTypes.default.object.isRequired,
|
|
131
|
-
attribute: _propTypes.default.string.isRequired,
|
|
132
|
-
value: _propTypes.default.string.isRequired
|
|
133
|
-
};
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { styled } from '@arcblock/ux/lib/Theme';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import Typography from '@mui/material/Typography';
|
|
4
|
-
import Img from '@arcblock/ux/lib/Img';
|
|
5
|
-
import Avatar from '@arcblock/did-connect/lib/Avatar';
|
|
6
|
-
|
|
7
|
-
const Div = styled('div')`
|
|
8
|
-
&.arcblock-blocklet {
|
|
9
|
-
padding: ${(props) => props.theme.spacing(2)} ${(props) => props.theme.spacing(2)} 0
|
|
10
|
-
${(props) => props.theme.spacing(2)};
|
|
11
|
-
}
|
|
12
|
-
.arcblock-blocklet__content {
|
|
13
|
-
cursor: pointer;
|
|
14
|
-
display: flex;
|
|
15
|
-
}
|
|
16
|
-
.arcblock-blocklet__cover {
|
|
17
|
-
width: 64px;
|
|
18
|
-
height: 64px;
|
|
19
|
-
margin-right: ${(props) => props.theme.spacing(2)};
|
|
20
|
-
overflow: hidden;
|
|
21
|
-
border-radius: 12px;
|
|
22
|
-
transform: translateZ(0);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.arcblock-blocklet__info {
|
|
26
|
-
flex: 1;
|
|
27
|
-
overflow: hidden;
|
|
28
|
-
border-bottom: 1px solid ${(props) => props.theme.palette.divider};
|
|
29
|
-
padding-bottom: ${(props) => props.theme.spacing(2)};
|
|
30
|
-
}
|
|
31
|
-
.arcblock-blocklet__text {
|
|
32
|
-
height: 57px;
|
|
33
|
-
overflow: hidden;
|
|
34
|
-
}
|
|
35
|
-
/* 设置多行文本溢出显示省略号 兼容fireFox、safari */
|
|
36
|
-
.arcblock-blocklet__title {
|
|
37
|
-
margin: 0;
|
|
38
|
-
font-size: 16px;
|
|
39
|
-
font-weight: 500;
|
|
40
|
-
overflow: hidden;
|
|
41
|
-
text-overflow: ellipsis;
|
|
42
|
-
white-space: nowrap;
|
|
43
|
-
}
|
|
44
|
-
.arcblock-blocklet__describe {
|
|
45
|
-
margin-top: ${(props) => props.theme.spacing(0.5)};
|
|
46
|
-
color: ${(props) => props.theme.palette.grey[600]};
|
|
47
|
-
font-size: 14px;
|
|
48
|
-
font-weight: 500;
|
|
49
|
-
line-height: 17px;
|
|
50
|
-
max-height: 34px;
|
|
51
|
-
overflow: hidden;
|
|
52
|
-
text-overflow: ellipsis;
|
|
53
|
-
display: -webkit-box;
|
|
54
|
-
-webkit-line-clamp: 2;
|
|
55
|
-
-webkit-box-orient: vertical;
|
|
56
|
-
word-break: break-word;
|
|
57
|
-
}
|
|
58
|
-
.ms-highlight {
|
|
59
|
-
color: ${(props) => props.theme.palette.primary.main};
|
|
60
|
-
}
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
export default function Blocklet({ cover, item, className, ...rest }) {
|
|
64
|
-
const { did, description, title, name } = item;
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<Div className={`${className} arcblock-blocklet`} {...rest}>
|
|
68
|
-
<div className="arcblock-blocklet__content">
|
|
69
|
-
{cover ? (
|
|
70
|
-
<div className="arcblock-blocklet__cover">
|
|
71
|
-
<Img src={cover} />
|
|
72
|
-
</div>
|
|
73
|
-
) : (
|
|
74
|
-
did && (
|
|
75
|
-
<div className="arcblock-blocklet__cover">
|
|
76
|
-
<Avatar did={did} size={64} />
|
|
77
|
-
</div>
|
|
78
|
-
)
|
|
79
|
-
)}
|
|
80
|
-
<div className="arcblock-blocklet__info">
|
|
81
|
-
<div className="arcblock-blocklet__text">
|
|
82
|
-
<Typography component="h3" variant="h3" className="arcblock-blocklet__title">
|
|
83
|
-
<ShowAttributes item={item} attribute="title" value={title || name} />
|
|
84
|
-
</Typography>
|
|
85
|
-
{description && (
|
|
86
|
-
<Typography component="div" variant="body2" className="arcblock-blocklet__describe">
|
|
87
|
-
<ShowAttributes item={item} attribute="description" value={description} />
|
|
88
|
-
</Typography>
|
|
89
|
-
)}
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</Div>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
Blocklet.propTypes = {
|
|
98
|
-
cover: PropTypes.string,
|
|
99
|
-
className: PropTypes.string,
|
|
100
|
-
item: PropTypes.object.isRequired,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
Blocklet.defaultProps = {
|
|
104
|
-
cover: null,
|
|
105
|
-
className: null,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
function ShowAttributes({ item, attribute, value }) {
|
|
109
|
-
if (item._formatted) {
|
|
110
|
-
// eslint-disable-next-line react/no-danger
|
|
111
|
-
return <span data-cy="bl-autocomplete-item" dangerouslySetInnerHTML={{ __html: item._formatted[attribute] }} />;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return value;
|
|
115
|
-
}
|
|
116
|
-
ShowAttributes.propTypes = {
|
|
117
|
-
item: PropTypes.object.isRequired,
|
|
118
|
-
attribute: PropTypes.string.isRequired,
|
|
119
|
-
value: PropTypes.string.isRequired,
|
|
120
|
-
};
|