@blocklet/list 0.10.19 → 0.10.20

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.
@@ -37,6 +37,9 @@ const en = {
37
37
  noBlockletPart2: '"were found',
38
38
  noCategoryResults1: 'No "',
39
39
  noCategoryResults2: '" Blocklets'
40
+ },
41
+ autocomplete: {
42
+ expandResult: 'Show all search results for "{name}" '
40
43
  }
41
44
  };
42
45
  const zh = {
@@ -69,6 +72,9 @@ const zh = {
69
72
  noBlockletPart2: '"相关的 Blocklets',
70
73
  noCategoryResults1: '无 "',
71
74
  noCategoryResults2: '" 类别的 Blocklets'
75
+ },
76
+ autocomplete: {
77
+ expandResult: '显示所有 “{name}” 的搜索结果 '
72
78
  }
73
79
  };
74
80
  var _default = {
@@ -15,8 +15,6 @@ var _autocompleteJs = require("@algolia/autocomplete-js");
15
15
 
16
16
  var _reactHotkeysHook = require("react-hotkeys-hook");
17
17
 
18
- var _react2 = require("@emotion/react");
19
-
20
18
  var _styles = require("@mui/material/styles");
21
19
 
22
20
  var _urlJoin = _interopRequireDefault(require("url-join"));
@@ -54,17 +52,25 @@ function Autocomplete(_ref) {
54
52
  t
55
53
  } = (0, _filter.useFilterContext)();
56
54
  const muiTheme = (0, _styles.useTheme)();
57
- const getResults = (0, _react.useCallback)(async params => {
55
+ const getBlocklets = (0, _react.useCallback)(async params => {
58
56
  const {
59
57
  data
60
58
  } = await storeApi.get(_constant.default.blockletsPath, {
61
59
  params
62
60
  });
63
- return data.dataList || [];
61
+ const blocklets = data.dataList || []; // 头部插入的一条 item 用于展示 `点击展开更多结果`,如果没有blocklet 返回,不展示
62
+
63
+ if (blocklets.length > 0) {
64
+ blocklets.unshift({
65
+ type: 'more-result'
66
+ });
67
+ }
68
+
69
+ return blocklets;
64
70
  }, [storeApi]);
65
71
  const onSubmit = (0, _react.useCallback)(e => {
66
- handleKeyword(e.state.query); // eslint-disable-next-line react-hooks/exhaustive-deps
67
- }, []);
72
+ handleKeyword(e.state.query);
73
+ }, [handleKeyword]);
68
74
 
69
75
  const setFocus = () => {
70
76
  if (containerRef.current) {
@@ -80,10 +86,22 @@ function Autocomplete(_ref) {
80
86
  };
81
87
 
82
88
  const onReset = (0, _react.useCallback)(autocompleteState => {
83
- handleKeyword();
89
+ autocompleteState.setIsOpen(false);
84
90
  setFocus();
85
- autocompleteState.setIsOpen(false); // eslint-disable-next-line react-hooks/exhaustive-deps
86
91
  }, []);
92
+ const onStateChange = (0, _react.useCallback)(_ref2 => {
93
+ let {
94
+ prevState,
95
+ state
96
+ } = _ref2;
97
+
98
+ // eslint-disable-next-line no-console
99
+ if (prevState.query !== state.query) {
100
+ if (!state.query) {
101
+ handleKeyword();
102
+ }
103
+ }
104
+ }, [handleKeyword]);
87
105
  (0, _reactHotkeysHook.useHotkeys)('/, ctrl + k, command + k', e => {
88
106
  e.stopPropagation();
89
107
  e.preventDefault();
@@ -108,10 +126,10 @@ function Autocomplete(_ref) {
108
126
  render: () => {}
109
127
  },
110
128
 
111
- render(_ref2, root) {
129
+ render(_ref3, root) {
112
130
  let {
113
131
  children
114
- } = _ref2;
132
+ } = _ref3;
115
133
 
116
134
  if (!panelRootRef.current || rootRef.current !== root) {
117
135
  var _panelRootRef$current;
@@ -136,21 +154,26 @@ function Autocomplete(_ref) {
136
154
  initialState: {
137
155
  query: filters.keyword
138
156
  },
157
+
158
+ onStateChange(autocompleteState) {
159
+ onStateChange(autocompleteState);
160
+ },
161
+
139
162
  onSubmit,
140
163
 
141
164
  onReset(autocompleteState) {
142
165
  onReset(autocompleteState);
143
166
  },
144
167
 
145
- getSources(_ref3) {
168
+ getSources(_ref4) {
146
169
  let {
147
170
  query
148
- } = _ref3;
171
+ } = _ref4;
149
172
 
150
173
  const params = _objectSpread(_objectSpread({}, filters), {}, {
151
174
  sortBy: _constant.default[filters.sortBy],
152
175
  page: 1,
153
- pageSize: 10,
176
+ pageSize: 5,
154
177
  keyword: query
155
178
  });
156
179
 
@@ -158,22 +181,33 @@ function Autocomplete(_ref) {
158
181
  sourceId: 'blocklets',
159
182
 
160
183
  getItems() {
161
- return getResults(params);
184
+ return getBlocklets(params);
162
185
  },
163
186
 
164
187
  // 选中后填充 搜索框中值
165
- getItemInputValue(_ref4) {
188
+ getItemInputValue(_ref5) {
166
189
  let {
167
190
  item
168
- } = _ref4;
191
+ } = _ref5;
192
+
193
+ if (item.type === 'more-result') {
194
+ return query;
195
+ }
196
+
169
197
  return item.title;
170
198
  },
171
199
 
172
- onSelect(_ref5) {
200
+ // 选中或者点击自动完成列表中的 item 时触发
201
+ onSelect(_ref6) {
173
202
  let {
174
203
  item
175
- } = _ref5;
176
- onSelect({
204
+ } = _ref6;
205
+
206
+ if (item.type === 'more-result') {
207
+ return null;
208
+ }
209
+
210
+ return onSelect({
177
211
  blocklet: item,
178
212
  detailUrl: (0, _urlJoin.default)(endpoint, "/blocklets/".concat(item.did)),
179
213
  storeUrl: endpoint
@@ -181,22 +215,27 @@ function Autocomplete(_ref) {
181
215
  },
182
216
 
183
217
  templates: {
184
- // eslint-disable-next-line react/no-unstable-nested-components
185
- item(_ref6) {
218
+ item(_ref7) {
186
219
  let {
187
220
  item
188
- } = _ref6;
221
+ } = _ref7;
189
222
  const logoUrl = item.logo ? (0, _urlJoin.default)(endpoint, 'assets', item.did, item.logo) : null;
223
+
224
+ if (item.type === 'more-result') {
225
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
226
+ children: t('autocomplete.expandResult', {
227
+ name: query
228
+ })
229
+ });
230
+ }
231
+
190
232
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_styles.ThemeProvider, {
191
233
  theme: muiTheme,
192
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_react2.ThemeProvider, {
193
- theme: muiTheme,
194
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_item.default, {
195
- item: item,
196
- did: item.did,
197
- description: item.description,
198
- cover: logoUrl
199
- })
234
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_item.default, {
235
+ item: item,
236
+ did: item.did,
237
+ description: item.description,
238
+ cover: logoUrl
200
239
  })
201
240
  });
202
241
  },
@@ -213,7 +252,7 @@ function Autocomplete(_ref) {
213
252
  return () => {
214
253
  search.destroy();
215
254
  };
216
- }, [endpoint, filters, getResults, muiTheme, onSubmit, onSelect, t, onReset]);
255
+ }, [endpoint, filters, muiTheme, onSubmit, onSelect, t, onReset, onStateChange, handleKeyword, getBlocklets]);
217
256
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
218
257
  className: "bl-search-container",
219
258
  ref: containerRef
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = Blocklet;
7
7
 
8
- var _styled = _interopRequireDefault(require("@emotion/styled"));
8
+ var _Theme = require("@arcblock/ux/lib/Theme");
9
9
 
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
 
@@ -35,7 +35,7 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
35
35
 
36
36
  function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
37
37
 
38
- const Div = _styled.default.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 background-color: yellow;\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]);
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 background-color: yellow;\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]);
39
39
 
40
40
  function Blocklet(_ref) {
41
41
  let {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/list",
3
- "version": "0.10.19",
3
+ "version": "0.10.20",
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": "813a039894ea2d1b8e1f4897c9f252b85df99091"
74
+ "gitHead": "325fb367d112f88af0d4c78b9e26e089f9d363f1"
75
75
  }
@@ -31,6 +31,9 @@ const en = {
31
31
  noCategoryResults1: 'No "',
32
32
  noCategoryResults2: '" Blocklets',
33
33
  },
34
+ autocomplete: {
35
+ expandResult: 'Show all search results for "{name}" ',
36
+ },
34
37
  };
35
38
 
36
39
  const zh = {
@@ -64,6 +67,9 @@ const zh = {
64
67
  noCategoryResults1: '无 "',
65
68
  noCategoryResults2: '" 类别的 Blocklets',
66
69
  },
70
+ autocomplete: {
71
+ expandResult: '显示所有 “{name}” 的搜索结果 ',
72
+ },
67
73
  };
68
74
 
69
75
  export default {
@@ -4,7 +4,6 @@ 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 EmotionThemeProvider } from '@emotion/react';
8
7
  import { ThemeProvider as MuiThemeProvider, useTheme } from '@mui/material/styles';
9
8
  import joinUrl from 'url-join';
10
9
 
@@ -20,18 +19,25 @@ export default function Autocomplete({ onSelect }) {
20
19
  const { storeApi, filters, endpoint, handleKeyword, t } = useFilterContext();
21
20
  const muiTheme = useTheme();
22
21
 
23
- const getResults = useCallback(
22
+ const getBlocklets = useCallback(
24
23
  async (params) => {
25
24
  const { data } = await storeApi.get(constant.blockletsPath, { params });
26
- return data.dataList || [];
25
+ const blocklets = data.dataList || [];
26
+ // 头部插入的一条 item 用于展示 `点击展开更多结果`,如果没有blocklet 返回,不展示
27
+ if (blocklets.length > 0) {
28
+ blocklets.unshift({ type: 'more-result' });
29
+ }
30
+ return blocklets;
27
31
  },
28
32
  [storeApi]
29
33
  );
30
34
 
31
- const onSubmit = useCallback((e) => {
32
- handleKeyword(e.state.query);
33
- // eslint-disable-next-line react-hooks/exhaustive-deps
34
- }, []);
35
+ const onSubmit = useCallback(
36
+ (e) => {
37
+ handleKeyword(e.state.query);
38
+ },
39
+ [handleKeyword]
40
+ );
35
41
 
36
42
  const setFocus = () => {
37
43
  if (containerRef.current) {
@@ -46,12 +52,22 @@ export default function Autocomplete({ onSelect }) {
46
52
  };
47
53
 
48
54
  const onReset = useCallback((autocompleteState) => {
49
- handleKeyword();
50
- setFocus();
51
55
  autocompleteState.setIsOpen(false);
52
- // eslint-disable-next-line react-hooks/exhaustive-deps
56
+ setFocus();
53
57
  }, []);
54
58
 
59
+ const onStateChange = useCallback(
60
+ ({ prevState, state }) => {
61
+ // eslint-disable-next-line no-console
62
+ if (prevState.query !== state.query) {
63
+ if (!state.query) {
64
+ handleKeyword();
65
+ }
66
+ }
67
+ },
68
+ [handleKeyword]
69
+ );
70
+
55
71
  useHotkeys(
56
72
  '/, ctrl + k, command + k',
57
73
  (e) => {
@@ -97,6 +113,9 @@ export default function Autocomplete({ onSelect }) {
97
113
  initialState: {
98
114
  query: filters.keyword,
99
115
  },
116
+ onStateChange(autocompleteState) {
117
+ onStateChange(autocompleteState);
118
+ },
100
119
  onSubmit,
101
120
  onReset(autocompleteState) {
102
121
  onReset(autocompleteState);
@@ -106,31 +125,42 @@ export default function Autocomplete({ onSelect }) {
106
125
  ...filters,
107
126
  sortBy: constant[filters.sortBy],
108
127
  page: 1,
109
- pageSize: 10,
128
+ pageSize: 5,
110
129
  keyword: query,
111
130
  };
112
131
  return debounced([
113
132
  {
114
133
  sourceId: 'blocklets',
115
134
  getItems() {
116
- return getResults(params);
135
+ return getBlocklets(params);
117
136
  },
118
137
  // 选中后填充 搜索框中值
119
138
  getItemInputValue({ item }) {
139
+ if (item.type === 'more-result') {
140
+ return query;
141
+ }
120
142
  return item.title;
121
143
  },
144
+ // 选中或者点击自动完成列表中的 item 时触发
122
145
  onSelect({ item }) {
123
- onSelect({ blocklet: item, detailUrl: joinUrl(endpoint, `/blocklets/${item.did}`), storeUrl: endpoint });
146
+ if (item.type === 'more-result') {
147
+ return null;
148
+ }
149
+ return onSelect({
150
+ blocklet: item,
151
+ detailUrl: joinUrl(endpoint, `/blocklets/${item.did}`),
152
+ storeUrl: endpoint,
153
+ });
124
154
  },
125
155
  templates: {
126
- // eslint-disable-next-line react/no-unstable-nested-components
127
156
  item({ item }) {
128
157
  const logoUrl = item.logo ? joinUrl(endpoint, 'assets', item.did, item.logo) : null;
158
+ if (item.type === 'more-result') {
159
+ return <div>{t('autocomplete.expandResult', { name: query })}</div>;
160
+ }
129
161
  return (
130
162
  <MuiThemeProvider theme={muiTheme}>
131
- <EmotionThemeProvider theme={muiTheme}>
132
- <Blocklet item={item} did={item.did} description={item.description} cover={logoUrl} />
133
- </EmotionThemeProvider>
163
+ <Blocklet item={item} did={item.did} description={item.description} cover={logoUrl} />
134
164
  </MuiThemeProvider>
135
165
  );
136
166
  },
@@ -146,7 +176,7 @@ export default function Autocomplete({ onSelect }) {
146
176
  return () => {
147
177
  search.destroy();
148
178
  };
149
- }, [endpoint, filters, getResults, muiTheme, onSubmit, onSelect, t, onReset]);
179
+ }, [endpoint, filters, muiTheme, onSubmit, onSelect, t, onReset, onStateChange, handleKeyword, getBlocklets]);
150
180
 
151
181
  return <div className="bl-search-container" ref={containerRef} />;
152
182
  }
@@ -1,10 +1,10 @@
1
- import styled from '@emotion/styled';
1
+ import { styled } from '@arcblock/ux/lib/Theme';
2
2
  import PropTypes from 'prop-types';
3
3
  import Typography from '@mui/material/Typography';
4
4
  import Img from '@arcblock/ux/lib/Img';
5
5
  import Avatar from '@arcblock/did-connect/lib/Avatar';
6
6
 
7
- const Div = styled.div`
7
+ const Div = styled('div')`
8
8
  &.arcblock-blocklet {
9
9
  padding: ${(props) => props.theme.spacing(2)} ${(props) => props.theme.spacing(2)} 0
10
10
  ${(props) => props.theme.spacing(2)};
package/src/libs/utils.js CHANGED
@@ -117,7 +117,6 @@ function debouncePromise(fn, time) {
117
117
  if (timerId) {
118
118
  clearTimeout(timerId);
119
119
  }
120
-
121
120
  return new Promise((resolve) => {
122
121
  timerId = setTimeout(() => resolve(fn(...args)), time);
123
122
  });