@blocklet/list 0.8.21 → 0.8.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/list",
3
- "version": "0.8.21",
3
+ "version": "0.8.24",
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.6",
40
+ "@arcblock/ux": "^2.1.7",
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": "04b04a68686b6d5136c255128e7f399ab95eb1f3"
61
+ "gitHead": "0127bb9206c38b378711109469684738205e07a6"
62
62
  }
package/src/base.js CHANGED
@@ -2,50 +2,53 @@ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
  import SortIcon from '@mui/icons-material/Sort';
4
4
  import { Box, Hidden } from '@mui/material';
5
+ import FaceIcon from '@mui/icons-material/Face';
5
6
 
6
7
  import { useFilterContext } from './contexts/filter';
7
8
  import CustomSelect from './components/custom-select';
8
- import FilterAuthor from './components/filter-author';
9
+ import { CustomChip, FilterIcon } from './components/filter';
9
10
  import { getSortOptions } from './libs/utils';
10
11
  import BlockletList from './components/list';
11
12
  import Aside from './components/aside';
12
13
  import Search from './components/search';
13
- import FilterOnMobile from './components/filter-mobile';
14
14
 
15
15
  const ListBase = () => {
16
- const { handleDeveloper, blockletList, filters, developerName, handleSort, t } = useFilterContext();
16
+ const {
17
+ handleDeveloper,
18
+ blockletList,
19
+ filters,
20
+ developerName,
21
+ handleSort,
22
+ handleCategory,
23
+ handlePrice,
24
+ t,
25
+ getCategoryLocale,
26
+ priceOptions,
27
+ } = useFilterContext();
28
+
29
+ const sortOptions = getSortOptions(t);
30
+ const sortLocale = sortOptions.find((f) => f.value === filters.sortBy)?.name || t('sort.sort');
31
+ const categoryLocale = getCategoryLocale(filters.category);
32
+ const priceLocale = priceOptions.find((price) => price.value === filters.price)?.name;
33
+
17
34
  return (
18
35
  <Box display="flex" alignItems="flex-start" height="100%">
19
36
  <Hidden mdDown>
20
37
  <Aside />
21
38
  </Hidden>
22
39
  <StyledMin>
23
- <Box className="marketplace-header" display="flex" alignItems="center">
24
- <Hidden mdDown>
25
- {!!filters.developer && (
26
- <FilterAuthor
27
- user={developerName}
28
- deleteUserTag={() => {
29
- handleDeveloper(null);
30
- }}
31
- />
32
- )}
33
- </Hidden>
34
- <Box mt={0} className="searchContainer">
35
- <Hidden mdUp>
36
- <StyledSearch className="search" placeholder={t('common.searchStore')} />
37
- </Hidden>
38
- </Box>
39
- <Box mt={0} ml="10px" className="filterContainer">
40
+ <Box className="filter-bar" display="flex" alignItems="center">
41
+ <StyledSearch className="search-container" placeholder={t('common.searchStore')} />
42
+ <Box mt={0} ml="16px" className="filter-container">
40
43
  <Hidden mdUp>
41
44
  {/* 小屏幕下类别 */}
42
- <FilterOnMobile />
45
+ <FilterIcon />
43
46
  </Hidden>
44
47
  {/* 排序选择器 */}
45
48
  <CustomSelect
46
49
  value={filters.sortBy}
47
- options={getSortOptions(t)}
48
- title={getSortOptions(t).find((f) => f.value === filters.sortBy)?.name || t('sort.sort')}
50
+ options={sortOptions}
51
+ title={sortLocale}
49
52
  icon={<SortIcon />}
50
53
  onChange={(v) => {
51
54
  handleSort(v);
@@ -53,19 +56,27 @@ const ListBase = () => {
53
56
  />
54
57
  </Box>
55
58
  </Box>
56
- <Hidden mdUp>
57
- <Box display="flex" flexWrap="wrap" alignItems="center">
58
- {!!filters.developer && (
59
- <FilterAuthor
60
- user={developerName}
61
- deleteUserTag={() => {
62
- handleDeveloper(null);
63
- }}
64
- style={{ marginBottom: '16px' }}
65
- />
66
- )}
67
- </Box>
68
- </Hidden>
59
+ <Box display="flex" flexWrap="wrap" alignItems="center" mb="16px">
60
+ <CustomChip
61
+ label={developerName}
62
+ icon={<FaceIcon />}
63
+ onDelete={() => {
64
+ handleDeveloper(null);
65
+ }}
66
+ />
67
+ <CustomChip
68
+ label={categoryLocale}
69
+ onDelete={() => {
70
+ handleCategory(null);
71
+ }}
72
+ />
73
+ <CustomChip
74
+ label={priceLocale}
75
+ onDelete={() => {
76
+ handlePrice(null);
77
+ }}
78
+ />
79
+ </Box>
69
80
  <BlockletList blocklets={blockletList} />
70
81
  </StyledMin>
71
82
  </Box>
@@ -76,45 +87,34 @@ const StyledMin = styled.main`
76
87
  flex: 1;
77
88
  width: 100%;
78
89
  min-width: 0;
79
- .marketplace-header {
90
+ .filter-bar {
80
91
  justify-content: space-between;
81
- margin-bottom: 20px;
92
+ margin-bottom: ${(props) => props.theme.spacing(2)};
82
93
  }
83
94
  .sort-button {
84
95
  white-space: nowrap;
85
96
  }
86
- .search {
97
+ .search-container {
98
+ flex: 2;
87
99
  margin-left: 0px;
88
100
  }
89
- /* 小于960px */
90
- @media (max-width: ${(props) => props.theme.breakpoints.values.md}px) {
91
- .searchContainer {
92
- flex: 1;
93
- }
94
- .search {
95
- width: 100%;
96
- }
97
- .filterContainer {
98
- flex: 1;
99
- display: flex;
100
- justify-content: flex-end;
101
- }
101
+
102
+ .filter-container {
103
+ flex: 1;
104
+ display: flex;
105
+ justify-content: flex-end;
102
106
  }
103
- @media (max-width: 750px) {
104
- .searchContainer {
107
+ @media (max-width: ${(props) => props.theme.breakpoints.values.md}px) {
108
+ .search-container {
105
109
  width: 100%;
110
+ margin-bottom: ${(props) => props.theme.spacing(2)};
106
111
  }
107
- .filterContainer {
108
- width: 100%;
112
+ .filter-container {
109
113
  margin-left: 0;
110
114
  display: flex;
111
115
  justify-content: flex-start;
112
116
  }
113
- .search {
114
- margin-bottom: 20px;
115
- width: 100%;
116
- }
117
- .marketplace-header {
117
+ .filter-bar {
118
118
  display: flex;
119
119
  flex-direction: column;
120
120
  align-items: flex-start;
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ import { useFilterContext } from '../contexts/filter';
5
+ import { FilterGroup } from './filter';
6
+
7
+ const Aside = () => {
8
+ const { selectedCategory, handleCategory, t, handlePrice, filters, categoryOptions, priceOptions } =
9
+ useFilterContext();
10
+
11
+ return (
12
+ <StyledAside>
13
+ <div>
14
+ <FilterGroup title={t('common.price')} options={priceOptions} value={filters.price} onChange={handlePrice} />
15
+ </div>
16
+ <div style={{ marginTop: '16px' }}>
17
+ <FilterGroup
18
+ title={t('common.category')}
19
+ options={categoryOptions}
20
+ value={selectedCategory}
21
+ onChange={handleCategory}
22
+ />
23
+ </div>
24
+ </StyledAside>
25
+ );
26
+ };
27
+
28
+ const StyledAside = styled.aside`
29
+ width: 220px;
30
+ margin-right: ${(props) => props.theme.spacing(2)};
31
+ height: 100%;
32
+ `;
33
+
34
+ Aside.propTypes = {};
35
+ Aside.defaultProps = {};
36
+ export default Aside;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from 'styled-components';
4
+ import { Chip } from '@mui/material';
5
+
6
+ const StyleDiv = styled.div`
7
+ .MuiChip-root {
8
+ border-radius: 4px;
9
+ height: initial;
10
+ text-transform: capitalize;
11
+ margin-right: ${(props) => props.theme.spacing(2)};
12
+ padding: 4px 0;
13
+ }
14
+ `;
15
+ const FilterChip = ({ label, icon, onDelete, ...containerProps }) => {
16
+ if (!label) return null;
17
+ return (
18
+ <StyleDiv {...containerProps}>
19
+ <Chip icon={icon} label={label} onDelete={onDelete} />
20
+ </StyleDiv>
21
+ );
22
+ };
23
+ FilterChip.propTypes = {
24
+ label: PropTypes.string,
25
+ onDelete: PropTypes.func,
26
+ icon: PropTypes.element,
27
+ };
28
+ FilterChip.defaultProps = {
29
+ onDelete: () => {},
30
+ icon: null,
31
+ label: null,
32
+ };
33
+ export default FilterChip;
@@ -2,19 +2,21 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from 'styled-components';
4
4
 
5
- function Content({ options, onChange, title, value }) {
5
+ function FilterGroup({ options, onChange, title, value }) {
6
6
  return (
7
7
  <StyledDiv>
8
8
  <div className="title">{title}</div>
9
9
  <div className="list">
10
10
  {options.map((item) => {
11
11
  return (
12
- <span
12
+ <div
13
+ title={item.name}
13
14
  key={item.value}
15
+ data-cy="filter"
14
16
  className={value === item.value ? 'select item' : 'item'}
15
17
  onClick={() => onChange(item.value)}>
16
18
  {item.name}
17
- </span>
19
+ </div>
18
20
  );
19
21
  })}
20
22
  </div>
@@ -26,29 +28,38 @@ const StyledDiv = styled.div`
26
28
  .title {
27
29
  font-size: 18px;
28
30
  font-weight: bold;
31
+ margin-bottom: ${(props) => props.theme.spacing(1)};
29
32
  }
30
33
  .list {
31
- display: flex;
32
- flex-direction: column;
33
- align-items: flex-start;
34
- margin-left: 8px;
35
34
  }
36
35
  .item {
37
- margin: 16px 0;
36
+ font-size: 16px;
37
+ padding: ${(props) => props.theme.spacing(1)};
38
+ color: #9397a1;
39
+ overflow: hidden;
40
+ text-overflow: ellipsis;
41
+ white-space: nowrap;
42
+ text-transform: capitalize;
38
43
  cursor: pointer;
44
+ &:hover {
45
+ background-color: ${(props) => props.theme.palette.grey[50]};
46
+ color: initial;
47
+ font-weight: bold;
48
+ }
39
49
  }
40
50
  .select {
41
51
  color: ${(props) => props.theme.palette.primary.main};
52
+ font-weight: bold;
42
53
  }
43
54
  `;
44
55
 
45
- Content.propTypes = {
56
+ FilterGroup.propTypes = {
46
57
  title: PropTypes.string.isRequired,
47
58
  options: PropTypes.array.isRequired,
48
59
  onChange: PropTypes.func.isRequired,
49
60
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
50
61
  };
51
- Content.defaultProps = {
62
+ FilterGroup.defaultProps = {
52
63
  value: null,
53
64
  };
54
- export default Content;
65
+ export default FilterGroup;
@@ -1,20 +1,26 @@
1
1
  import React, { useState } from 'react';
2
- // import PropTypes from 'prop-types';
3
2
  import styled from 'styled-components';
4
3
  import FilterAltOutlinedIcon from '@mui/icons-material/FilterAltOutlined';
5
4
  import Dialog from '@arcblock/ux/lib/Dialog';
6
5
  import Button from '@mui/material/Button';
7
6
 
8
7
  import { useFilterContext } from '../../contexts/filter';
9
- import Content from './content';
10
- import { getCategoriesOption, getPrices } from '../../libs/utils';
8
+ import FilterGroup from './group';
11
9
 
12
- function MobileFilter() {
13
- const { selectedCategory, handleCategory, t, handlePrice, filters, categoryList, locale } = useFilterContext();
10
+ function FilterIcon() {
11
+ const { selectedCategory, handleCategory, t, handlePrice, filters, categoryOptions, priceOptions } =
12
+ useFilterContext();
14
13
  const [open, setOpen] = useState(false);
15
14
 
16
- const categoriesOption = getCategoriesOption(categoryList, locale);
17
- const prices = getPrices(t);
15
+ const handelChange = (type, value) => {
16
+ if (type === 'category') {
17
+ handleCategory(value);
18
+ }
19
+ if (type === 'price') {
20
+ handlePrice(value);
21
+ }
22
+ setOpen(false);
23
+ };
18
24
 
19
25
  return (
20
26
  <StyledDiv>
@@ -22,13 +28,24 @@ function MobileFilter() {
22
28
  <FilterAltOutlinedIcon className="filter-icon" fontSize="small" />
23
29
  </Button>
24
30
  <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
+ <FilterGroup
32
+ title={t('common.price')}
33
+ options={priceOptions}
34
+ value={filters.price}
35
+ onChange={(v) => {
36
+ handelChange('price', v);
37
+ }}
31
38
  />
39
+ <div style={{ marginTop: '16px' }}>
40
+ <FilterGroup
41
+ title={t('common.category')}
42
+ options={categoryOptions}
43
+ value={selectedCategory}
44
+ onChange={(v) => {
45
+ handelChange('category', v);
46
+ }}
47
+ />
48
+ </div>
32
49
  </Dialog>
33
50
  </StyledDiv>
34
51
  );
@@ -47,6 +64,6 @@ const StyledDiv = styled.div`
47
64
  }
48
65
  `;
49
66
 
50
- MobileFilter.propTypes = {};
51
- MobileFilter.defaultProps = {};
52
- export default MobileFilter;
67
+ FilterIcon.propTypes = {};
68
+ FilterIcon.defaultProps = {};
69
+ export default FilterIcon;
@@ -0,0 +1,5 @@
1
+ import FilterIcon from './icon';
2
+ import CustomChip from './custom-chip';
3
+ import FilterGroup from './group';
4
+
5
+ export { FilterIcon, CustomChip, FilterGroup };
@@ -105,6 +105,11 @@ const StyledGrid = styled(Grid)`
105
105
  padding-right: ${(props) => props.theme.spacing(0.5)};
106
106
  }
107
107
  }
108
+ @media (min-width: ${(props) => props.theme.breakpoints.values.sm}px) {
109
+ &.MuiGrid-item {
110
+ margin-bottom: ${(props) => props.theme.spacing(2)};
111
+ }
112
+ }
108
113
  `;
109
114
  const CustomEmpty = styled(Empty)`
110
115
  text-align: center;
@@ -60,11 +60,10 @@ Search.defaultProps = {
60
60
  };
61
61
  const StyledSearch = styled(OutlinedInput)`
62
62
  background-color: #fff;
63
- border-radius: 12px;
64
- font-size: 16px;
65
- margin: 0 10px;
63
+ font-size: 14px;
64
+ border-radius: 6px;
66
65
  .MuiInputBase-input {
67
- padding: 12px 0px 12px 0px;
66
+ padding: 8px 0 8px 10px;
68
67
  }
69
68
  .MuiOutlinedInput-notchedOutline {
70
69
  border: none;
@@ -75,13 +74,6 @@ const StyledSearch = styled(OutlinedInput)`
75
74
  color: transparent;
76
75
  }
77
76
  }
78
- @media (max-width: ${(props) => props.theme.breakpoints.values.md}px) {
79
- font-size: 14px;
80
- border-radius: 6px;
81
- .MuiInputBase-input {
82
- padding: 8px 0 8px 10px;
83
- }
84
- }
85
77
  `;
86
78
 
87
79
  const StyledSearchIcon = styled(SearchIcon)`
@@ -5,28 +5,17 @@ import orderBy from 'lodash/orderBy';
5
5
  import axios from 'axios';
6
6
  // import joinUrl from 'url-join';
7
7
 
8
- import { getCategories, filterBlockletByPrice, replaceTranslate } from '../libs/utils';
8
+ import { getCategories, filterBlockletByPrice, replaceTranslate, getPrices, getCategoryOptions } from '../libs/utils';
9
9
  import translations from '../assets/locale';
10
10
  import { propTypes, defaultProps } from '../libs/prop-types';
11
11
 
12
12
  const Filter = createContext({});
13
13
  const { Provider, Consumer } = Filter;
14
14
 
15
- function FilterProvider({
16
- onSelectBlocklet,
17
- selectedBlocklets,
18
- filters,
19
- children,
20
- baseUrl,
21
- endpoint,
22
- locale,
23
- blockletRender,
24
- onFilterChange,
25
- }) {
15
+ function FilterProvider({ filters, children, baseUrl, endpoint, locale, blockletRender, onFilterChange }) {
26
16
  const storeApi = axios.create({
27
17
  baseURL: endpoint,
28
18
  });
29
-
30
19
  const {
31
20
  data: allBlocklets,
32
21
  error: fetchBlockletsError,
@@ -53,11 +42,11 @@ function FilterProvider({
53
42
  { initialData: [], manual: true }
54
43
  );
55
44
 
56
- const selectedCategory = filters.category;
57
-
58
- const hasDeveloperFilter = !!filters.developer;
45
+ const finalFilters = { sortBy: 'popularity', sortDirection: 'desc', ...filters };
46
+ const selectedCategory = finalFilters.category;
47
+ const hasDeveloperFilter = !!finalFilters.developer;
59
48
  const categoryState = useMemo(() => {
60
- return !hasDeveloperFilter ? { data: allCategories } : getCategories(allBlocklets, filters.developer);
49
+ return !hasDeveloperFilter ? { data: allCategories } : getCategories(allBlocklets, finalFilters.developer);
61
50
  }, [hasDeveloperFilter, allCategories]);
62
51
 
63
52
  const blockletList = useMemo(() => {
@@ -71,16 +60,18 @@ function FilterProvider({
71
60
  publishAt: sortByPublish,
72
61
  };
73
62
 
74
- let result = allBlocklets || [];
63
+ let blocklets = allBlocklets || [];
75
64
  // 按照付费/免费筛选
76
- result = filterBlockletByPrice(result, filters.price);
65
+ blocklets = filterBlockletByPrice(blocklets, finalFilters.price);
77
66
  // 按照分类筛选
78
- result = result.filter((item) => (selectedCategory ? item?.category?.name === selectedCategory : true));
67
+ blocklets = blocklets.filter((item) => (selectedCategory ? item?.category?.name === selectedCategory : true));
79
68
  // 按照作者筛选
80
- result = result.filter((item) => (filters?.developer ? item.owner.did === filters.developer : true));
81
- const lowerSearch = filters?.keyword?.toLocaleLowerCase() || '';
69
+ blocklets = blocklets.filter((item) =>
70
+ finalFilters?.developer ? item.owner.did === finalFilters.developer : true
71
+ );
72
+ const lowerSearch = finalFilters?.keyword?.toLocaleLowerCase() || '';
82
73
  // 按照搜索筛选
83
- result = result.filter((item) => {
74
+ blocklets = blocklets.filter((item) => {
84
75
  return (
85
76
  (item?.title || item?.name)?.toLocaleLowerCase().includes(lowerSearch) ||
86
77
  item.description?.toLocaleLowerCase().includes(lowerSearch) ||
@@ -88,8 +79,8 @@ function FilterProvider({
88
79
  );
89
80
  });
90
81
  // 排序
91
- return orderBy(result, [sortMap[filters.sortBy]], [filters.sortDirection]);
92
- }, [allBlocklets, filters]);
82
+ return orderBy(blocklets, [sortMap[finalFilters.sortBy]], [finalFilters.sortDirection]);
83
+ }, [allBlocklets, finalFilters]);
93
84
 
94
85
  const categoryList = useMemo(() => {
95
86
  const list = categoryState.data || [];
@@ -105,50 +96,53 @@ function FilterProvider({
105
96
 
106
97
  return replaceTranslate(translations[locale][key], data);
107
98
  };
99
+
100
+ const categoryOptions = useMemo(() => getCategoryOptions(categoryList, locale), [categoryList, locale]);
101
+ const priceOptions = getPrices(translate);
102
+
108
103
  const filterStore = {
109
104
  errors: { fetchBlockletsError, fetchCategoriesError },
110
105
  loadings: { fetchBlockletsLoading, fetchCategoriesLoading },
111
106
  endpoint,
112
107
  blockletList,
113
108
  t: translate,
114
- filters: { sortBy: 'popularity', sortDirection: 'desc', ...filters },
109
+ filters: finalFilters,
115
110
  selectedCategory,
116
111
  categoryList,
117
112
  baseUrl,
118
113
  blockletRender,
119
114
  locale,
120
- selectedBlocklets,
121
- onSelectBlocklet,
115
+ categoryOptions,
116
+ priceOptions,
122
117
  handleSort: (sort) => {
123
118
  const changeData = {
124
- ...filters,
119
+ ...finalFilters,
125
120
  sortBy: sort,
126
121
  sortDirection: sort === 'nameAsc' ? 'asc' : 'desc',
127
122
  };
128
123
  onFilterChange(changeData);
129
124
  },
130
125
  handleKeyword: (keyWord) => {
131
- const changeData = { ...filters, keyword: keyWord || undefined };
126
+ const changeData = { ...finalFilters, keyword: keyWord || undefined };
132
127
  onFilterChange(changeData);
133
128
  },
134
129
  handlePrice: (price) => {
135
130
  const changeData = {
136
- ...filters,
137
- price: price === filters.price ? undefined : price,
131
+ ...finalFilters,
132
+ price: price === finalFilters.price ? undefined : price,
138
133
  };
139
134
  onFilterChange(changeData);
140
135
  },
141
136
  handleCategory: (category) => {
142
- if (category === 'all') {
143
- const changeData = { ...filters, category: undefined };
144
- onFilterChange(changeData);
145
- } else {
146
- const changeData = { ...filters, category: category === filters.category ? undefined : category };
147
- onFilterChange(changeData);
137
+ let finalCategory = category;
138
+ if (category === 'all' || category === finalFilters.category) {
139
+ finalCategory = undefined;
148
140
  }
141
+ const changeData = { ...finalFilters, category: finalCategory };
142
+ onFilterChange(changeData);
149
143
  },
150
144
  handleDeveloper: (developer) => {
151
- const changeData = { ...filters, developer: developer || undefined };
145
+ const changeData = { ...finalFilters, developer: developer || undefined };
152
146
  onFilterChange(changeData);
153
147
  },
154
148
  getCategoryLocale: (category) => {
@@ -161,7 +155,7 @@ function FilterProvider({
161
155
  return result;
162
156
  },
163
157
  get developerName() {
164
- return allBlocklets.find((i) => i.owner.did === filters.developer)?.owner?.name || '';
158
+ return allBlocklets.find((blocklet) => blocklet.owner.did === finalFilters.developer)?.owner?.name || '';
165
159
  },
166
160
  };
167
161
 
package/src/libs/utils.js CHANGED
@@ -35,7 +35,7 @@ const getPrices = (t) => {
35
35
  { name: t('blocklet.payment'), value: 'payment' },
36
36
  ];
37
37
  };
38
- const getCategoriesOption = (list = [], locale = 'en') => {
38
+ const getCategoryOptions = (list = [], locale = 'en') => {
39
39
  return list.map((item) => ({ name: item.locales[locale], value: item.name }));
40
40
  };
41
41
  /**
@@ -117,5 +117,5 @@ export {
117
117
  formatError,
118
118
  removeUndefined,
119
119
  urlStringify,
120
- getCategoriesOption,
120
+ getCategoryOptions,
121
121
  };