@blocklet/list 0.8.18 → 0.8.21
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 +6 -21
- package/lib/components/filter-mobile/content.js +51 -0
- package/lib/components/filter-mobile/index.js +77 -0
- package/lib/components/list/list.js +2 -3
- package/lib/contexts/filter.js +1 -1
- package/lib/libs/utils.js +13 -2
- package/package.json +3 -3
- package/src/base.js +9 -22
- package/src/components/filter-mobile/content.js +54 -0
- package/src/components/filter-mobile/index.js +52 -0
- package/src/components/list/list.js +3 -3
- package/src/contexts/filter.js +1 -1
- package/src/libs/utils.js +4 -0
- package/lib/components/category-select.js +0 -55
- package/src/components/category-select.js +0 -43
package/lib/base.js
CHANGED
|
@@ -11,8 +11,6 @@ var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
|
11
11
|
|
|
12
12
|
var _Sort = _interopRequireDefault(require("@mui/icons-material/Sort"));
|
|
13
13
|
|
|
14
|
-
var _FilterList = _interopRequireDefault(require("@mui/icons-material/FilterList"));
|
|
15
|
-
|
|
16
14
|
var _material = require("@mui/material");
|
|
17
15
|
|
|
18
16
|
var _filter = require("./contexts/filter");
|
|
@@ -29,12 +27,12 @@ var _aside = _interopRequireDefault(require("./components/aside"));
|
|
|
29
27
|
|
|
30
28
|
var _search = _interopRequireDefault(require("./components/search"));
|
|
31
29
|
|
|
32
|
-
var
|
|
30
|
+
var _filterMobile = _interopRequireDefault(require("./components/filter-mobile"));
|
|
33
31
|
|
|
34
32
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
33
|
|
|
36
34
|
const ListBase = () => {
|
|
37
|
-
var _getSortOptions$find
|
|
35
|
+
var _getSortOptions$find;
|
|
38
36
|
|
|
39
37
|
const {
|
|
40
38
|
handleDeveloper,
|
|
@@ -42,8 +40,7 @@ const ListBase = () => {
|
|
|
42
40
|
filters,
|
|
43
41
|
developerName,
|
|
44
42
|
handleSort,
|
|
45
|
-
t
|
|
46
|
-
handlePrice
|
|
43
|
+
t
|
|
47
44
|
} = (0, _filter.useFilterContext)();
|
|
48
45
|
return /*#__PURE__*/_react.default.createElement(_material.Box, {
|
|
49
46
|
display: "flex",
|
|
@@ -76,7 +73,7 @@ const ListBase = () => {
|
|
|
76
73
|
className: "filterContainer"
|
|
77
74
|
}, /*#__PURE__*/_react.default.createElement(_material.Hidden, {
|
|
78
75
|
mdUp: true
|
|
79
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
76
|
+
}, /*#__PURE__*/_react.default.createElement(_filterMobile.default, null)), /*#__PURE__*/_react.default.createElement(_customSelect.default, {
|
|
80
77
|
value: filters.sortBy,
|
|
81
78
|
options: (0, _utils.getSortOptions)(t),
|
|
82
79
|
title: ((_getSortOptions$find = (0, _utils.getSortOptions)(t).find(f => f.value === filters.sortBy)) === null || _getSortOptions$find === void 0 ? void 0 : _getSortOptions$find.name) || t('sort.sort'),
|
|
@@ -89,8 +86,7 @@ const ListBase = () => {
|
|
|
89
86
|
}, /*#__PURE__*/_react.default.createElement(_material.Box, {
|
|
90
87
|
display: "flex",
|
|
91
88
|
flexWrap: "wrap",
|
|
92
|
-
alignItems: "center"
|
|
93
|
-
justifyContent: filters.developer ? 'space-between' : 'flex-end'
|
|
89
|
+
alignItems: "center"
|
|
94
90
|
}, !!filters.developer && /*#__PURE__*/_react.default.createElement(_filterAuthor.default, {
|
|
95
91
|
user: developerName,
|
|
96
92
|
deleteUserTag: () => {
|
|
@@ -99,17 +95,6 @@ const ListBase = () => {
|
|
|
99
95
|
style: {
|
|
100
96
|
marginBottom: '16px'
|
|
101
97
|
}
|
|
102
|
-
}), /*#__PURE__*/_react.default.createElement(_customSelect.default, {
|
|
103
|
-
value: filters.price,
|
|
104
|
-
icon: /*#__PURE__*/_react.default.createElement(_FilterList.default, null),
|
|
105
|
-
options: (0, _utils.getPrices)(t),
|
|
106
|
-
title: ((_getPrices$find = (0, _utils.getPrices)(t).find(f => f.value === filters.price)) === null || _getPrices$find === void 0 ? void 0 : _getPrices$find.name) || t('common.price'),
|
|
107
|
-
onChange: v => {
|
|
108
|
-
handlePrice(v);
|
|
109
|
-
},
|
|
110
|
-
style: {
|
|
111
|
-
marginBottom: '16px'
|
|
112
|
-
}
|
|
113
98
|
}))), /*#__PURE__*/_react.default.createElement(_list.default, {
|
|
114
99
|
blocklets: blockletList
|
|
115
100
|
})));
|
|
@@ -118,7 +103,7 @@ const ListBase = () => {
|
|
|
118
103
|
const StyledMin = _styledComponents.default.main.withConfig({
|
|
119
104
|
displayName: "base__StyledMin",
|
|
120
105
|
componentId: "sc-wumzlv-0"
|
|
121
|
-
})(["flex:1;width:100%;min-width:0;.marketplace-header{justify-content:space-between;margin-bottom:20px;}.sort-button{white-space:nowrap;}.search{margin-left:0px;}@media (max-width:", "px){.searchContainer{flex:1;}.search{width:100%;}.filterContainer{flex:1;display:flex;justify-content:flex-end;}}@media (max-width:750px){.searchContainer{width:100%;}.filterContainer{width:100%;margin-left:0;display:flex;justify-content:
|
|
106
|
+
})(["flex:1;width:100%;min-width:0;.marketplace-header{justify-content:space-between;margin-bottom:20px;}.sort-button{white-space:nowrap;}.search{margin-left:0px;}@media (max-width:", "px){.searchContainer{flex:1;}.search{width:100%;}.filterContainer{flex:1;display:flex;justify-content:flex-end;}}@media (max-width:750px){.searchContainer{width:100%;}.filterContainer{width:100%;margin-left:0;display:flex;justify-content:flex-start;}.search{margin-bottom:20px;width:100%;}.marketplace-header{display:flex;flex-direction:column;align-items:flex-start;}}@media (max-width:", "px){.sort-button{font-size:12px;}}"], props => props.theme.breakpoints.values.md, props => props.theme.breakpoints.values.md);
|
|
122
107
|
|
|
123
108
|
const StyledSearch = (0, _styledComponents.default)(_search.default).withConfig({
|
|
124
109
|
displayName: "base__StyledSearch",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
function Content(_ref) {
|
|
17
|
+
let {
|
|
18
|
+
options,
|
|
19
|
+
onChange,
|
|
20
|
+
title,
|
|
21
|
+
value
|
|
22
|
+
} = _ref;
|
|
23
|
+
return /*#__PURE__*/_react.default.createElement(StyledDiv, null, /*#__PURE__*/_react.default.createElement("div", {
|
|
24
|
+
className: "title"
|
|
25
|
+
}, title), /*#__PURE__*/_react.default.createElement("div", {
|
|
26
|
+
className: "list"
|
|
27
|
+
}, options.map(item => {
|
|
28
|
+
return /*#__PURE__*/_react.default.createElement("span", {
|
|
29
|
+
key: item.value,
|
|
30
|
+
className: value === item.value ? 'select item' : 'item',
|
|
31
|
+
onClick: () => onChange(item.value)
|
|
32
|
+
}, item.name);
|
|
33
|
+
})));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const StyledDiv = _styledComponents.default.div.withConfig({
|
|
37
|
+
displayName: "content__StyledDiv",
|
|
38
|
+
componentId: "sc-16pmlm6-0"
|
|
39
|
+
})([".title{font-size:18px;font-weight:bold;}.list{display:flex;flex-direction:column;align-items:flex-start;margin-left:8px;}.item{margin:16px 0;cursor:pointer;}.select{color:", ";}"], props => props.theme.palette.primary.main);
|
|
40
|
+
|
|
41
|
+
Content.propTypes = {
|
|
42
|
+
title: _propTypes.default.string.isRequired,
|
|
43
|
+
options: _propTypes.default.array.isRequired,
|
|
44
|
+
onChange: _propTypes.default.func.isRequired,
|
|
45
|
+
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number])
|
|
46
|
+
};
|
|
47
|
+
Content.defaultProps = {
|
|
48
|
+
value: null
|
|
49
|
+
};
|
|
50
|
+
var _default = Content;
|
|
51
|
+
exports.default = _default;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
11
|
+
|
|
12
|
+
var _FilterAltOutlined = _interopRequireDefault(require("@mui/icons-material/FilterAltOutlined"));
|
|
13
|
+
|
|
14
|
+
var _Dialog = _interopRequireDefault(require("@arcblock/ux/lib/Dialog"));
|
|
15
|
+
|
|
16
|
+
var _Button = _interopRequireDefault(require("@mui/material/Button"));
|
|
17
|
+
|
|
18
|
+
var _filter = require("../../contexts/filter");
|
|
19
|
+
|
|
20
|
+
var _content = _interopRequireDefault(require("./content"));
|
|
21
|
+
|
|
22
|
+
var _utils = require("../../libs/utils");
|
|
23
|
+
|
|
24
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
|
+
|
|
26
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
27
|
+
|
|
28
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
29
|
+
|
|
30
|
+
// import PropTypes from 'prop-types';
|
|
31
|
+
function MobileFilter() {
|
|
32
|
+
const {
|
|
33
|
+
selectedCategory,
|
|
34
|
+
handleCategory,
|
|
35
|
+
t,
|
|
36
|
+
handlePrice,
|
|
37
|
+
filters,
|
|
38
|
+
categoryList,
|
|
39
|
+
locale
|
|
40
|
+
} = (0, _filter.useFilterContext)();
|
|
41
|
+
const [open, setOpen] = (0, _react.useState)(false);
|
|
42
|
+
const categoriesOption = (0, _utils.getCategoriesOption)(categoryList, locale);
|
|
43
|
+
const prices = (0, _utils.getPrices)(t);
|
|
44
|
+
return /*#__PURE__*/_react.default.createElement(StyledDiv, null, /*#__PURE__*/_react.default.createElement(_Button.default, {
|
|
45
|
+
variant: "outlined",
|
|
46
|
+
className: "filter-button",
|
|
47
|
+
onClick: () => setOpen(true)
|
|
48
|
+
}, /*#__PURE__*/_react.default.createElement(_FilterAltOutlined.default, {
|
|
49
|
+
className: "filter-icon",
|
|
50
|
+
fontSize: "small"
|
|
51
|
+
})), /*#__PURE__*/_react.default.createElement(_Dialog.default, {
|
|
52
|
+
fullWidth: true,
|
|
53
|
+
title: "",
|
|
54
|
+
open: open,
|
|
55
|
+
onClose: () => setOpen(false)
|
|
56
|
+
}, /*#__PURE__*/_react.default.createElement(_content.default, {
|
|
57
|
+
title: t('common.price'),
|
|
58
|
+
options: prices,
|
|
59
|
+
value: filters.price,
|
|
60
|
+
onChange: handlePrice
|
|
61
|
+
}), /*#__PURE__*/_react.default.createElement(_content.default, {
|
|
62
|
+
title: t('common.category'),
|
|
63
|
+
options: categoriesOption,
|
|
64
|
+
value: selectedCategory,
|
|
65
|
+
onChange: handleCategory
|
|
66
|
+
})));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const StyledDiv = _styledComponents.default.div.withConfig({
|
|
70
|
+
displayName: "filter-mobile__StyledDiv",
|
|
71
|
+
componentId: "sc-5csoa5-0"
|
|
72
|
+
})([".filter-button{margin-right:16px;border-color:rgb(240,240,240);padding:5px 8px;min-width:initial;}.filter-icon{cursor:pointer;color:", ";}"], props => props.theme.palette.grey[500]);
|
|
73
|
+
|
|
74
|
+
MobileFilter.propTypes = {};
|
|
75
|
+
MobileFilter.defaultProps = {};
|
|
76
|
+
var _default = MobileFilter;
|
|
77
|
+
exports.default = _default;
|
|
@@ -105,8 +105,7 @@ function BlockletList(_ref) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
return /*#__PURE__*/_react.default.createElement(_Grid.default, Object.assign({
|
|
108
|
-
container: true
|
|
109
|
-
spacing: 4
|
|
108
|
+
container: true
|
|
110
109
|
}, rest), blocklets.map(blocklet => /*#__PURE__*/_react.default.createElement(StyledGrid, {
|
|
111
110
|
item: true,
|
|
112
111
|
lg: 4,
|
|
@@ -128,7 +127,7 @@ BlockletList.defaultProps = {};
|
|
|
128
127
|
const StyledGrid = (0, _styledComponents.default)(_Grid.default).withConfig({
|
|
129
128
|
displayName: "list__StyledGrid",
|
|
130
129
|
componentId: "sc-jzgpev-0"
|
|
131
|
-
})(["@media (max-width:", "px){&.MuiGrid-item{padding-bottom:0px;
|
|
130
|
+
})(["@media (max-width:", "px){&.MuiGrid-item{padding-bottom:0px;margin-left:", ";padding-right:", ";}}"], props => props.theme.breakpoints.values.sm, props => props.theme.spacing(-2), props => props.theme.spacing(0.5));
|
|
132
131
|
const CustomEmpty = (0, _styledComponents.default)(_Empty.default).withConfig({
|
|
133
132
|
displayName: "list__CustomEmpty",
|
|
134
133
|
componentId: "sc-jzgpev-1"
|
package/lib/contexts/filter.js
CHANGED
|
@@ -206,7 +206,7 @@ function FilterProvider(_ref) {
|
|
|
206
206
|
onFilterChange(changeData);
|
|
207
207
|
} else {
|
|
208
208
|
const changeData = _objectSpread(_objectSpread({}, filters), {}, {
|
|
209
|
-
category
|
|
209
|
+
category: category === filters.category ? undefined : category
|
|
210
210
|
});
|
|
211
211
|
|
|
212
212
|
onFilterChange(changeData);
|
package/lib/libs/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = exports.getStoreDetail = exports.getSortOptions = exports.getPrices = exports.getCategories = exports.formatLogoPath = exports.formatError = exports.filterBlockletByPrice = void 0;
|
|
6
|
+
exports.urlStringify = exports.replaceTranslate = exports.removeUndefined = exports.getStoreDetail = exports.getSortOptions = exports.getPrices = exports.getCategoriesOption = exports.getCategories = exports.formatLogoPath = exports.formatError = exports.filterBlockletByPrice = void 0;
|
|
7
7
|
|
|
8
8
|
var _urlJoin = _interopRequireDefault(require("url-join"));
|
|
9
9
|
|
|
@@ -47,6 +47,17 @@ const getPrices = t => {
|
|
|
47
47
|
value: 'payment'
|
|
48
48
|
}];
|
|
49
49
|
};
|
|
50
|
+
|
|
51
|
+
exports.getPrices = getPrices;
|
|
52
|
+
|
|
53
|
+
const getCategoriesOption = function getCategoriesOption() {
|
|
54
|
+
let list = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
55
|
+
let locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en';
|
|
56
|
+
return list.map(item => ({
|
|
57
|
+
name: item.locales[locale],
|
|
58
|
+
value: item.name
|
|
59
|
+
}));
|
|
60
|
+
};
|
|
50
61
|
/**
|
|
51
62
|
* 从开发者所属 blocklets 中的得到 Categories
|
|
52
63
|
* @param {*} list
|
|
@@ -55,7 +66,7 @@ const getPrices = t => {
|
|
|
55
66
|
*/
|
|
56
67
|
|
|
57
68
|
|
|
58
|
-
exports.
|
|
69
|
+
exports.getCategoriesOption = getCategoriesOption;
|
|
59
70
|
|
|
60
71
|
const getCategories = (list, developerDid) => {
|
|
61
72
|
const filterList = list.filter(item => developerDid ? item.owner.did === developerDid : true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/list",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.21",
|
|
4
4
|
"description": "Common ux components of blocklet",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"react": ">=18.1.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@arcblock/ux": "^2.1.
|
|
40
|
+
"@arcblock/ux": "^2.1.6",
|
|
41
41
|
"@emotion/react": "^11.9.0",
|
|
42
42
|
"@emotion/styled": "^11.8.1",
|
|
43
43
|
"@mui/icons-material": "^5.6.2",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
"babel-plugin-inline-react-svg": "^2.0.1",
|
|
59
59
|
"babel-plugin-styled-components": "^1.10.7"
|
|
60
60
|
},
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "04b04a68686b6d5136c255128e7f399ab95eb1f3"
|
|
62
62
|
}
|
package/src/base.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
import SortIcon from '@mui/icons-material/Sort';
|
|
4
|
-
import FilterListIcon from '@mui/icons-material/FilterList';
|
|
5
4
|
import { Box, Hidden } from '@mui/material';
|
|
6
5
|
|
|
7
6
|
import { useFilterContext } from './contexts/filter';
|
|
8
7
|
import CustomSelect from './components/custom-select';
|
|
9
8
|
import FilterAuthor from './components/filter-author';
|
|
10
|
-
import { getSortOptions
|
|
9
|
+
import { getSortOptions } from './libs/utils';
|
|
11
10
|
import BlockletList from './components/list';
|
|
12
11
|
import Aside from './components/aside';
|
|
13
12
|
import Search from './components/search';
|
|
14
|
-
import
|
|
13
|
+
import FilterOnMobile from './components/filter-mobile';
|
|
15
14
|
|
|
16
15
|
const ListBase = () => {
|
|
17
|
-
const { handleDeveloper, blockletList, filters, developerName, handleSort, t
|
|
16
|
+
const { handleDeveloper, blockletList, filters, developerName, handleSort, t } = useFilterContext();
|
|
18
17
|
return (
|
|
19
18
|
<Box display="flex" alignItems="flex-start" height="100%">
|
|
20
19
|
<Hidden mdDown>
|
|
@@ -39,8 +38,10 @@ const ListBase = () => {
|
|
|
39
38
|
</Box>
|
|
40
39
|
<Box mt={0} ml="10px" className="filterContainer">
|
|
41
40
|
<Hidden mdUp>
|
|
42
|
-
|
|
41
|
+
{/* 小屏幕下类别 */}
|
|
42
|
+
<FilterOnMobile />
|
|
43
43
|
</Hidden>
|
|
44
|
+
{/* 排序选择器 */}
|
|
44
45
|
<CustomSelect
|
|
45
46
|
value={filters.sortBy}
|
|
46
47
|
options={getSortOptions(t)}
|
|
@@ -53,11 +54,7 @@ const ListBase = () => {
|
|
|
53
54
|
</Box>
|
|
54
55
|
</Box>
|
|
55
56
|
<Hidden mdUp>
|
|
56
|
-
<Box
|
|
57
|
-
display="flex"
|
|
58
|
-
flexWrap="wrap"
|
|
59
|
-
alignItems="center"
|
|
60
|
-
justifyContent={filters.developer ? 'space-between' : 'flex-end'}>
|
|
57
|
+
<Box display="flex" flexWrap="wrap" alignItems="center">
|
|
61
58
|
{!!filters.developer && (
|
|
62
59
|
<FilterAuthor
|
|
63
60
|
user={developerName}
|
|
@@ -67,17 +64,6 @@ const ListBase = () => {
|
|
|
67
64
|
style={{ marginBottom: '16px' }}
|
|
68
65
|
/>
|
|
69
66
|
)}
|
|
70
|
-
{/* 筛选付费/免费 */}
|
|
71
|
-
<CustomSelect
|
|
72
|
-
value={filters.price}
|
|
73
|
-
icon={<FilterListIcon />}
|
|
74
|
-
options={getPrices(t)}
|
|
75
|
-
title={getPrices(t).find((f) => f.value === filters.price)?.name || t('common.price')}
|
|
76
|
-
onChange={(v) => {
|
|
77
|
-
handlePrice(v);
|
|
78
|
-
}}
|
|
79
|
-
style={{ marginBottom: '16px' }}
|
|
80
|
-
/>
|
|
81
67
|
</Box>
|
|
82
68
|
</Hidden>
|
|
83
69
|
<BlockletList blocklets={blockletList} />
|
|
@@ -100,6 +86,7 @@ const StyledMin = styled.main`
|
|
|
100
86
|
.search {
|
|
101
87
|
margin-left: 0px;
|
|
102
88
|
}
|
|
89
|
+
/* 小于960px */
|
|
103
90
|
@media (max-width: ${(props) => props.theme.breakpoints.values.md}px) {
|
|
104
91
|
.searchContainer {
|
|
105
92
|
flex: 1;
|
|
@@ -121,7 +108,7 @@ const StyledMin = styled.main`
|
|
|
121
108
|
width: 100%;
|
|
122
109
|
margin-left: 0;
|
|
123
110
|
display: flex;
|
|
124
|
-
justify-content:
|
|
111
|
+
justify-content: flex-start;
|
|
125
112
|
}
|
|
126
113
|
.search {
|
|
127
114
|
margin-bottom: 20px;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
|
|
5
|
+
function Content({ options, onChange, title, value }) {
|
|
6
|
+
return (
|
|
7
|
+
<StyledDiv>
|
|
8
|
+
<div className="title">{title}</div>
|
|
9
|
+
<div className="list">
|
|
10
|
+
{options.map((item) => {
|
|
11
|
+
return (
|
|
12
|
+
<span
|
|
13
|
+
key={item.value}
|
|
14
|
+
className={value === item.value ? 'select item' : 'item'}
|
|
15
|
+
onClick={() => onChange(item.value)}>
|
|
16
|
+
{item.name}
|
|
17
|
+
</span>
|
|
18
|
+
);
|
|
19
|
+
})}
|
|
20
|
+
</div>
|
|
21
|
+
</StyledDiv>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const StyledDiv = styled.div`
|
|
26
|
+
.title {
|
|
27
|
+
font-size: 18px;
|
|
28
|
+
font-weight: bold;
|
|
29
|
+
}
|
|
30
|
+
.list {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-direction: column;
|
|
33
|
+
align-items: flex-start;
|
|
34
|
+
margin-left: 8px;
|
|
35
|
+
}
|
|
36
|
+
.item {
|
|
37
|
+
margin: 16px 0;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
.select {
|
|
41
|
+
color: ${(props) => props.theme.palette.primary.main};
|
|
42
|
+
}
|
|
43
|
+
`;
|
|
44
|
+
|
|
45
|
+
Content.propTypes = {
|
|
46
|
+
title: PropTypes.string.isRequired,
|
|
47
|
+
options: PropTypes.array.isRequired,
|
|
48
|
+
onChange: PropTypes.func.isRequired,
|
|
49
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
50
|
+
};
|
|
51
|
+
Content.defaultProps = {
|
|
52
|
+
value: null,
|
|
53
|
+
};
|
|
54
|
+
export default Content;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
// import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import FilterAltOutlinedIcon from '@mui/icons-material/FilterAltOutlined';
|
|
5
|
+
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
6
|
+
import Button from '@mui/material/Button';
|
|
7
|
+
|
|
8
|
+
import { useFilterContext } from '../../contexts/filter';
|
|
9
|
+
import Content from './content';
|
|
10
|
+
import { getCategoriesOption, getPrices } from '../../libs/utils';
|
|
11
|
+
|
|
12
|
+
function MobileFilter() {
|
|
13
|
+
const { selectedCategory, handleCategory, t, handlePrice, filters, categoryList, locale } = useFilterContext();
|
|
14
|
+
const [open, setOpen] = useState(false);
|
|
15
|
+
|
|
16
|
+
const categoriesOption = getCategoriesOption(categoryList, locale);
|
|
17
|
+
const prices = getPrices(t);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<StyledDiv>
|
|
21
|
+
<Button variant="outlined" className="filter-button" onClick={() => setOpen(true)}>
|
|
22
|
+
<FilterAltOutlinedIcon className="filter-icon" fontSize="small" />
|
|
23
|
+
</Button>
|
|
24
|
+
<Dialog fullWidth title="" open={open} onClose={() => setOpen(false)}>
|
|
25
|
+
<Content title={t('common.price')} options={prices} value={filters.price} onChange={handlePrice} />
|
|
26
|
+
<Content
|
|
27
|
+
title={t('common.category')}
|
|
28
|
+
options={categoriesOption}
|
|
29
|
+
value={selectedCategory}
|
|
30
|
+
onChange={handleCategory}
|
|
31
|
+
/>
|
|
32
|
+
</Dialog>
|
|
33
|
+
</StyledDiv>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const StyledDiv = styled.div`
|
|
38
|
+
.filter-button {
|
|
39
|
+
margin-right: 16px;
|
|
40
|
+
border-color: rgb(240, 240, 240);
|
|
41
|
+
padding: 5px 8px;
|
|
42
|
+
min-width: initial;
|
|
43
|
+
}
|
|
44
|
+
.filter-icon {
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
color: ${(props) => props.theme.palette.grey[500]};
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
MobileFilter.propTypes = {};
|
|
51
|
+
MobileFilter.defaultProps = {};
|
|
52
|
+
export default MobileFilter;
|
|
@@ -81,7 +81,7 @@ export default function BlockletList({ blocklets, ...rest }) {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
return (
|
|
84
|
-
<Grid container
|
|
84
|
+
<Grid container {...rest}>
|
|
85
85
|
{blocklets.map((blocklet) => (
|
|
86
86
|
<StyledGrid item lg={4} md={6} sm={6} xs={12} key={blocklet.did} data-blocklet-did={blocklet.did}>
|
|
87
87
|
{blockletRender({ blocklet, blocklets: blockletList })}
|
|
@@ -101,8 +101,8 @@ const StyledGrid = styled(Grid)`
|
|
|
101
101
|
@media (max-width: ${(props) => props.theme.breakpoints.values.sm}px) {
|
|
102
102
|
&.MuiGrid-item {
|
|
103
103
|
padding-bottom: 0px;
|
|
104
|
-
|
|
105
|
-
padding-right:
|
|
104
|
+
margin-left: ${(props) => props.theme.spacing(-2)};
|
|
105
|
+
padding-right: ${(props) => props.theme.spacing(0.5)};
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
`;
|
package/src/contexts/filter.js
CHANGED
|
@@ -143,7 +143,7 @@ function FilterProvider({
|
|
|
143
143
|
const changeData = { ...filters, category: undefined };
|
|
144
144
|
onFilterChange(changeData);
|
|
145
145
|
} else {
|
|
146
|
-
const changeData = { ...filters, category };
|
|
146
|
+
const changeData = { ...filters, category: category === filters.category ? undefined : category };
|
|
147
147
|
onFilterChange(changeData);
|
|
148
148
|
}
|
|
149
149
|
},
|
package/src/libs/utils.js
CHANGED
|
@@ -35,6 +35,9 @@ const getPrices = (t) => {
|
|
|
35
35
|
{ name: t('blocklet.payment'), value: 'payment' },
|
|
36
36
|
];
|
|
37
37
|
};
|
|
38
|
+
const getCategoriesOption = (list = [], locale = 'en') => {
|
|
39
|
+
return list.map((item) => ({ name: item.locales[locale], value: item.name }));
|
|
40
|
+
};
|
|
38
41
|
/**
|
|
39
42
|
* 从开发者所属 blocklets 中的得到 Categories
|
|
40
43
|
* @param {*} list
|
|
@@ -114,4 +117,5 @@ export {
|
|
|
114
117
|
formatError,
|
|
115
118
|
removeUndefined,
|
|
116
119
|
urlStringify,
|
|
120
|
+
getCategoriesOption,
|
|
117
121
|
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.default = void 0;
|
|
7
|
-
|
|
8
|
-
var _react = _interopRequireDefault(require("react"));
|
|
9
|
-
|
|
10
|
-
var _material = require("@mui/material");
|
|
11
|
-
|
|
12
|
-
var _filter = require("../contexts/filter");
|
|
13
|
-
|
|
14
|
-
var _customSelect = _interopRequireDefault(require("./custom-select"));
|
|
15
|
-
|
|
16
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 小屏幕下的分类选择器
|
|
20
|
-
* @returns
|
|
21
|
-
*/
|
|
22
|
-
const CategorySelect = () => {
|
|
23
|
-
var _categoryList$find;
|
|
24
|
-
|
|
25
|
-
const {
|
|
26
|
-
categoryList,
|
|
27
|
-
selectedCategory,
|
|
28
|
-
handleCategory,
|
|
29
|
-
t,
|
|
30
|
-
locale
|
|
31
|
-
} = (0, _filter.useFilterContext)();
|
|
32
|
-
|
|
33
|
-
const itemRender = item => {
|
|
34
|
-
return /*#__PURE__*/_react.default.createElement(_material.MenuItem, {
|
|
35
|
-
className: ['my-select__option', selectedCategory !== null && selectedCategory !== void 0 && selectedCategory.includes(item.name) ? 'my-select__option--active' : ''].join(' '),
|
|
36
|
-
key: item._id,
|
|
37
|
-
value: item.name,
|
|
38
|
-
onClick: () => handleCategory(item.name)
|
|
39
|
-
}, item.locales[locale]);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return /*#__PURE__*/_react.default.createElement(_customSelect.default, {
|
|
43
|
-
value: selectedCategory || 'all',
|
|
44
|
-
options: categoryList,
|
|
45
|
-
title: ((_categoryList$find = categoryList.find(i => i.name === selectedCategory)) === null || _categoryList$find === void 0 ? void 0 : _categoryList$find.locales[locale]) || t('category.all'),
|
|
46
|
-
itemRender: itemRender,
|
|
47
|
-
prepend: /*#__PURE__*/_react.default.createElement(_material.MenuItem, {
|
|
48
|
-
value: "all",
|
|
49
|
-
onClick: () => handleCategory('all')
|
|
50
|
-
}, t('category.all'))
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
var _default = CategorySelect;
|
|
55
|
-
exports.default = _default;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { MenuItem } from '@mui/material';
|
|
3
|
-
|
|
4
|
-
import { useFilterContext } from '../contexts/filter';
|
|
5
|
-
import CustomSelect from './custom-select';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 小屏幕下的分类选择器
|
|
9
|
-
* @returns
|
|
10
|
-
*/
|
|
11
|
-
const CategorySelect = () => {
|
|
12
|
-
const { categoryList, selectedCategory, handleCategory, t, locale } = useFilterContext();
|
|
13
|
-
|
|
14
|
-
const itemRender = (item) => {
|
|
15
|
-
return (
|
|
16
|
-
<MenuItem
|
|
17
|
-
className={['my-select__option', selectedCategory?.includes(item.name) ? 'my-select__option--active' : ''].join(
|
|
18
|
-
' '
|
|
19
|
-
)}
|
|
20
|
-
key={item._id}
|
|
21
|
-
value={item.name}
|
|
22
|
-
onClick={() => handleCategory(item.name)}>
|
|
23
|
-
{item.locales[locale]}
|
|
24
|
-
</MenuItem>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<CustomSelect
|
|
30
|
-
value={selectedCategory || 'all'}
|
|
31
|
-
options={categoryList}
|
|
32
|
-
title={categoryList.find((i) => i.name === selectedCategory)?.locales[locale] || t('category.all')}
|
|
33
|
-
itemRender={itemRender}
|
|
34
|
-
prepend={
|
|
35
|
-
<MenuItem value="all" onClick={() => handleCategory('all')}>
|
|
36
|
-
{t('category.all')}
|
|
37
|
-
</MenuItem>
|
|
38
|
-
}
|
|
39
|
-
/>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default CategorySelect;
|