@blaze-cms/react-page-builder 0.123.0-alpha.8 → 0.123.1-alpha.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +108 -794
  2. package/lib/components/Card/Card.js +20 -6
  3. package/lib/components/Card/Card.js.map +1 -1
  4. package/lib/components/Card/CardContainer.js +20 -4
  5. package/lib/components/Card/CardContainer.js.map +1 -1
  6. package/lib/components/CarouselWrapper.js +12 -5
  7. package/lib/components/CarouselWrapper.js.map +1 -1
  8. package/lib/components/DataSummary/helpers/get-link-based-on-value.js +4 -0
  9. package/lib/components/DataSummary/helpers/get-link-based-on-value.js.map +1 -1
  10. package/lib/components/List/components/Cards/CardsRenderItem.js +23 -4
  11. package/lib/components/List/components/Cards/CardsRenderItem.js.map +1 -1
  12. package/lib/components/Menu/Menu.js +4 -3
  13. package/lib/components/Menu/Menu.js.map +1 -1
  14. package/lib/components/SearchContent/index.js +35 -25
  15. package/lib/components/SearchContent/index.js.map +1 -1
  16. package/lib/components/SearchFilter/SearchFilter/FiltersList.js +16 -11
  17. package/lib/components/SearchFilter/SearchFilter/FiltersList.js.map +1 -1
  18. package/lib/components/SearchFilter/SearchFilter/SearchFilter.js +15 -50
  19. package/lib/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
  20. package/lib/components/SearchFilter/components/Select.js +22 -10
  21. package/lib/components/SearchFilter/components/Select.js.map +1 -1
  22. package/lib/components/index.js +5 -0
  23. package/lib/components/index.js.map +1 -1
  24. package/lib/constants/index.js +5 -2
  25. package/lib/constants/index.js.map +1 -1
  26. package/lib-es/components/Card/Card.js +18 -4
  27. package/lib-es/components/Card/Card.js.map +1 -1
  28. package/lib-es/components/Card/CardContainer.js +21 -5
  29. package/lib-es/components/Card/CardContainer.js.map +1 -1
  30. package/lib-es/components/CarouselWrapper.js +12 -5
  31. package/lib-es/components/CarouselWrapper.js.map +1 -1
  32. package/lib-es/components/DataSummary/helpers/get-link-based-on-value.js +5 -1
  33. package/lib-es/components/DataSummary/helpers/get-link-based-on-value.js.map +1 -1
  34. package/lib-es/components/List/components/Cards/CardsRenderItem.js +23 -4
  35. package/lib-es/components/List/components/Cards/CardsRenderItem.js.map +1 -1
  36. package/lib-es/components/Menu/Menu.js +4 -3
  37. package/lib-es/components/Menu/Menu.js.map +1 -1
  38. package/lib-es/components/SearchContent/index.js +32 -24
  39. package/lib-es/components/SearchContent/index.js.map +1 -1
  40. package/lib-es/components/SearchFilter/SearchFilter/FiltersList.js +20 -16
  41. package/lib-es/components/SearchFilter/SearchFilter/FiltersList.js.map +1 -1
  42. package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js +10 -40
  43. package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
  44. package/lib-es/components/SearchFilter/components/Select.js +22 -6
  45. package/lib-es/components/SearchFilter/components/Select.js.map +1 -1
  46. package/lib-es/components/index.js +4 -1
  47. package/lib-es/components/index.js.map +1 -1
  48. package/lib-es/constants/index.js +3 -1
  49. package/lib-es/constants/index.js.map +1 -1
  50. package/package.json +3 -3
  51. package/src/components/Card/Card.js +28 -3
  52. package/src/components/Card/CardContainer.js +18 -2
  53. package/src/components/CarouselWrapper.js +8 -5
  54. package/src/components/DataSummary/helpers/get-link-based-on-value.js +9 -1
  55. package/src/components/List/components/Cards/CardsRenderItem.js +22 -3
  56. package/src/components/Menu/Menu.js +4 -3
  57. package/src/components/SearchContent/index.js +30 -20
  58. package/src/components/SearchFilter/SearchFilter/FiltersList.js +5 -2
  59. package/src/components/SearchFilter/SearchFilter/SearchFilter.js +113 -148
  60. package/src/components/SearchFilter/components/Select.js +29 -6
  61. package/src/components/index.js +2 -1
  62. package/src/constants/index.js +3 -1
  63. package/tests/unit/src/components/Card/__snapshots__/Card.test.js.snap +10 -10
  64. package/tests/unit/src/components/Card/__snapshots__/CardContainer.test.js.snap +8 -8
  65. package/tests/unit/src/components/Card/__snapshots__/CardRender.test.js.snap +2 -2
  66. package/tests/unit/src/components/Card/mockData.js +2 -0
  67. package/tests/unit/src/components/DataSummary/helpers/get-link-based-on-value.test.js +29 -0
  68. package/tests/unit/src/components/List/components/Cards/__snapshots__/CardsRender.test.js.snap +12 -12
  69. package/tests/unit/src/components/Menu/Menu.test.js +3 -1
  70. package/tests/unit/src/components/Menu/__snapshots__/Menu.test.js.snap +3 -0
  71. package/tests/unit/src/components/SearchFilter/SearchFilter/SearchFilter.test.js +64 -86
  72. package/tests/unit/src/components/SearchFilter/SearchFilter/__snapshots__/SearchFilter.test.js.snap +133 -61
  73. package/tests/unit/src/components/SearchFilter/components/Select.test.js +58 -4
  74. package/tests/unit/src/components/SearchFilter/components/__snapshots__/Select.test.js.snap +28 -5
  75. package/tests/unit/src/components/__snapshots__/index.test.js.snap +4 -0
@@ -1,4 +1,8 @@
1
- import { DATA_SUMMARY_EMAIL_REGEX, DATA_SUMMARY_URL_REGEX } from '../../../constants';
1
+ import {
2
+ DATA_SUMMARY_EMAIL_REGEX,
3
+ DATA_SUMMARY_URL_REGEX,
4
+ DATA_SUMMARY_TEL_REGEX
5
+ } from '../../../constants';
2
6
 
3
7
  function getLinkBasedOnValue(value) {
4
8
  if (DATA_SUMMARY_EMAIL_REGEX.test(value)) {
@@ -8,6 +12,10 @@ function getLinkBasedOnValue(value) {
8
12
  return value;
9
13
  }
10
14
 
15
+ if (DATA_SUMMARY_TEL_REGEX.test(value)) {
16
+ return `tel:${value}`;
17
+ }
18
+
11
19
  return '';
12
20
  }
13
21
 
@@ -21,7 +21,12 @@ const CardsRenderItem = ({
21
21
  propsToDisplay,
22
22
  shouldRenderBanner,
23
23
  bannerIndex,
24
- priority
24
+ priority,
25
+ enableOverlay,
26
+ autoScrollTimer,
27
+ arrowSize,
28
+ overlayModifier,
29
+ titleOverlayModifier
25
30
  }) => {
26
31
  const {
27
32
  initialOffset,
@@ -73,6 +78,10 @@ const CardsRenderItem = ({
73
78
  gtmId={name}
74
79
  gtmChildren={gtmChildren}
75
80
  priority={priority}
81
+ arrowSize={arrowSize}
82
+ enableOverlay={enableOverlay}
83
+ overlayModifier={overlayModifier}
84
+ titleOverlayModifier={titleOverlayModifier}
76
85
  {...cardProps}
77
86
  />
78
87
  </div>
@@ -96,7 +105,12 @@ CardsRenderItem.propTypes = {
96
105
  modifier: PropTypes.string,
97
106
  cardChildren: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
98
107
  gtmChildren: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
99
- priority: PropTypes.bool
108
+ priority: PropTypes.bool,
109
+ enableOverlay: PropTypes.bool,
110
+ overlayModifier: PropTypes.string,
111
+ titleOverlayModifier: PropTypes.string,
112
+ autoScrollTimer: PropTypes.number,
113
+ arrowSize: PropTypes.string
100
114
  };
101
115
 
102
116
  CardsRenderItem.defaultProps = {
@@ -106,7 +120,12 @@ CardsRenderItem.defaultProps = {
106
120
  propsToDisplay: [],
107
121
  modifier: '',
108
122
  cardChildren: [],
109
- gtmChildren: []
123
+ gtmChildren: [],
124
+ enableOverlay: false,
125
+ autoScrollTimer: 0,
126
+ overlayModifier: '',
127
+ titleOverlayModifier: '',
128
+ arrowSize: ''
110
129
  };
111
130
 
112
131
  export default CardsRenderItem;
@@ -73,7 +73,7 @@ const Menu = ({
73
73
  <ul className={isMobile ? childrenMobileModifier : childrenDesktopModifier}>
74
74
  {logoOnDesktop &&
75
75
  logoOnDesktopAlignment === 'left' && (
76
- <a href="/" className="">
76
+ <a href="/" className="menu--desktop__logo-wrapper">
77
77
  <img
78
78
  src={logoOnMobileUrl}
79
79
  alt={logoOnMobileAlt}
@@ -106,7 +106,7 @@ const Menu = ({
106
106
  )}
107
107
  {logoOnDesktop &&
108
108
  logoOnDesktopAlignment === 'right' && (
109
- <a href="/" className="">
109
+ <a href="/" className="menu--desktop__logo-wrapper">
110
110
  <img
111
111
  src={logoOnMobileUrl}
112
112
  alt={logoOnMobileAlt}
@@ -123,7 +123,7 @@ const Menu = ({
123
123
  Menu.propTypes = {
124
124
  collapse: PropTypes.bool.isRequired,
125
125
  logoOnMobile: PropTypes.bool.isRequired,
126
- logoOnDesktop: PropTypes.bool.isRequired,
126
+ logoOnDesktop: PropTypes.bool,
127
127
  logoOnMobileUrl: PropTypes.string,
128
128
  logoOnMobileAlt: PropTypes.string,
129
129
  logoOnMobileModifier: PropTypes.string,
@@ -144,6 +144,7 @@ Menu.propTypes = {
144
144
  };
145
145
 
146
146
  Menu.defaultProps = {
147
+ logoOnDesktop: false,
147
148
  logoOnMobileUrl: '',
148
149
  logoOnMobileAlt: '',
149
150
  logoOnMobileModifier: '',
@@ -7,11 +7,13 @@ import BlazeLink from '../BlazeLink';
7
7
 
8
8
  const SearchContent = ({
9
9
  entity,
10
+ searchInputAlignment,
10
11
  searchInputWrapperMobile,
11
12
  searchInputWrapperDesktop,
13
+ displayCollapsed,
12
14
  isMobile
13
15
  }) => {
14
- const [collapsed, setCollapsed] = useState(true);
16
+ const [collapsed, setCollapsed] = useState(displayCollapsed);
15
17
  const [searchTerm, setSearchTerm] = useState(null);
16
18
  const router = useRouter();
17
19
 
@@ -49,20 +51,26 @@ const SearchContent = ({
49
51
  });
50
52
 
51
53
  if (loading) return null;
52
- if (error) return `Error! ${error}`;
54
+ if (error) return null;
53
55
 
54
56
  const handleClick = (e, url) => {
55
57
  e.preventDefault();
56
58
  router.push(url);
57
59
  };
58
60
 
61
+ const handleKeyPress = e => {
62
+ if (e.key === 'Enter' && e.target.value !== '') {
63
+ router.push(`/search?search_term=${e.target.value}`);
64
+ }
65
+ };
66
+
59
67
  const renderResults = () => {
60
68
  // eslint-disable-next-line no-undef
61
69
  const { results } = data?.searchPublishedContent;
62
70
 
63
71
  if (results && searchTerm && searchTerm !== '') {
64
72
  return results.map(({ name, url }) => {
65
- if (name.match(searchTerm)) {
73
+ if (name.includes(searchTerm)) {
66
74
  return (
67
75
  <BlazeLink href={url} onClick={e => handleClick(e, url)}>
68
76
  {name}
@@ -81,10 +89,10 @@ const SearchContent = ({
81
89
 
82
90
  return collapsed ? (
83
91
  <div className={isMobile ? searchInputWrapperMobile : searchInputWrapperDesktop}>
84
- <div className="w-11 mx-auto">
85
- <label className="relative block">
86
- <span className="absolute inset-y-0 right-3 flex items-center pl-2 cursor-pointer">
87
- <svg className="h-5 w-5 fill-slate-300" viewBox="0 0 20 20">
92
+ <div className="search-content--collapse__wrapper">
93
+ <label className="search-content--collapse__label">
94
+ <span className="search-content--collapse__icon_wrapper">
95
+ <svg className="search-content--collapse__icon" viewBox="0 0 20 20">
88
96
  <path
89
97
  fillRule="evenodd"
90
98
  d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
@@ -92,14 +100,13 @@ const SearchContent = ({
92
100
  />
93
101
  </svg>
94
102
  </span>
95
- <span className="sr-only">Search</span>
96
103
  <input
97
104
  onFocus={() => setCollapsed(false)}
98
105
  onChange={e => setSearchTerm(e.target.value)}
99
106
  type="text"
100
107
  name="search"
101
108
  value=""
102
- className="disabled:bg-white block bg-white w-full rounded-none border-white py-2 pl-5 pr-3 placeholder:italic placeholder:text-gray-400 focus:outline-none sm:text-sm"
109
+ className="search-content--collapse__input"
103
110
  />
104
111
  </label>
105
112
  </div>
@@ -107,10 +114,10 @@ const SearchContent = ({
107
114
  ) : (
108
115
  <>
109
116
  <div className={`${isMobile ? searchInputWrapperMobile : searchInputWrapperDesktop}`}>
110
- <div className="w-96 mx-auto rounded-3xl">
111
- <label className="relative block">
112
- <span className="absolute inset-y-0 right-3 flex items-center pl-2">
113
- <svg className="h-5 w-5 fill-slate-300" viewBox="0 0 20 20">
117
+ <div className="search-content--expanded__wrapper">
118
+ <label className="search-content--expanded__label">
119
+ <span className="search-content--expanded__icon_wrapper">
120
+ <svg className="search-content--expanded__icon" viewBox="0 0 20 20">
114
121
  <path
115
122
  fillRule="evenodd"
116
123
  d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
@@ -118,12 +125,12 @@ const SearchContent = ({
118
125
  />
119
126
  </svg>
120
127
  </span>
121
- <span className="sr-only">Search</span>
122
128
  <input
123
129
  type="text"
124
130
  name="search"
125
131
  onChange={e => setSearchTerm(e.target.value)}
126
- className="block w-full rounded-full rounded-white py-2 pl-3 pr-3 placeholder:italic placeholder:text-slate-400 focus:outline-none sm:text-sm"
132
+ onKeyPress={handleKeyPress}
133
+ className="search-content--expanded__input"
127
134
  placeholder="Search for anything..."
128
135
  onBlur={() => {
129
136
  if (!searchTerm || searchTerm === '') setCollapsed(true);
@@ -133,12 +140,12 @@ const SearchContent = ({
133
140
  </div>
134
141
  {data &&
135
142
  searchResultsMessage !== '' && (
136
- <div className="bg-white ml-1 mr-1 rounded rounded-lg absolute top-16 flex flex-col z-50 border-2 border-gray-50 w-96">
137
- <div className="px-2">
143
+ <div className="search-content--results__wrapper">
144
+ <div className="search-content--results__wrapper--message">
138
145
  <div className="text-sm pt-2">{searchResultsMessage}</div>
139
146
 
140
- <div className="text-left px-4 py-2">
141
- <div className="text-bold">{renderResults()}</div>
147
+ <div className="search-content--results__message">
148
+ <div className="search-content--results__content">{renderResults()}</div>
142
149
  </div>
143
150
  </div>
144
151
  </div>
@@ -149,9 +156,11 @@ const SearchContent = ({
149
156
  };
150
157
 
151
158
  SearchContent.propTypes = {
159
+ searchInputAlignment: PropTypes.string,
152
160
  searchInputWrapperMobile: PropTypes.string,
153
161
  searchInputWrapperDesktop: PropTypes.string,
154
162
  isMobile: PropTypes.bool,
163
+ displayCollapsed: PropTypes.bool,
155
164
  entity: PropTypes.string.isRequired
156
165
  };
157
166
 
@@ -159,7 +168,8 @@ SearchContent.defaultProps = {
159
168
  searchInputAlignment: '',
160
169
  searchInputWrapperMobile: '',
161
170
  searchInputWrapperDesktop: '',
162
- isMobile: false
171
+ isMobile: false,
172
+ displayCollapsed: false
163
173
  };
164
174
 
165
175
  export default SearchContent;
@@ -15,7 +15,7 @@ const FiltersList = ({
15
15
  }) => {
16
16
  const { itemId } = useContext(MainContext);
17
17
 
18
- return filters.map(({ type, label, propsToDisplay, rangeInterval, elementTitle }, index) => {
18
+ return filters.map(({ type, label, propsToDisplay, elementTitle, ...otherProps }, index) => {
19
19
  if (!propsToDisplay && !propsToDisplay.length) return null;
20
20
 
21
21
  const dynamicKey = [itemId, index].join('-');
@@ -32,6 +32,7 @@ const FiltersList = ({
32
32
  key={dynamicKey}
33
33
  className="filter__section filter__section--search-refine filter__section--search">
34
34
  <TextSearch
35
+ {...otherProps}
35
36
  label={label}
36
37
  elementTitle={elementTitle}
37
38
  searchValue={filterValues[SEARCH_TERM]}
@@ -47,6 +48,7 @@ const FiltersList = ({
47
48
  key={dynamicKey}
48
49
  className="filter__section filter__section--search-refine filter__section--checkboxes">
49
50
  <Checkbox
51
+ {...otherProps}
50
52
  data={data}
51
53
  prop={propsToDisplay[0]}
52
54
  label={label}
@@ -66,6 +68,7 @@ const FiltersList = ({
66
68
  key={dynamicKey}
67
69
  className="filter__section filter__section--search-refine filter__section--selects">
68
70
  <SelectFilter
71
+ {...otherProps}
69
72
  data={data}
70
73
  prop={propsToDisplay[0]}
71
74
  label={label}
@@ -83,9 +86,9 @@ const FiltersList = ({
83
86
  !!areAggregationsAvailable && (
84
87
  <div key={dynamicKey} className="range-slider__wrapper">
85
88
  <Range
89
+ {...otherProps}
86
90
  dataAggregations={dataAggregations}
87
91
  propsToDisplay={propsToDisplay}
88
- rangeInterval={rangeInterval}
89
92
  label={label}
90
93
  elementTitle={elementTitle}
91
94
  entity={entity}
@@ -44,8 +44,6 @@ const SearchFilter = ({
44
44
  groupAfterDesktop,
45
45
  groupAfterMobile
46
46
  }) => {
47
- const [isDesktop, setIsDesktop] = useState(true);
48
- const [pageWidth, setPageWidth] = useState(null);
49
47
  const [moreFiltersMobileCollapsed, setMoreFiltersMobileCollapsed] = useState(true);
50
48
  const [moreFiltersDesktopCollapsed, setMoreFiltersDesktopCollapsed] = useState(true);
51
49
  const [filterValues, dispatch] = useReducer(reducer, initialFilterValues);
@@ -55,27 +53,6 @@ const SearchFilter = ({
55
53
  handleSearch(newQuery);
56
54
  }, 200);
57
55
 
58
- useEffect(
59
- () => {
60
- if (window && !pageWidth) {
61
- setPageWidth(window.innerWidth);
62
- setIsDesktop(isDeviceDesktop());
63
- }
64
-
65
- const handleResize = ({ target: { innerWidth } }) => {
66
- setIsDesktop(isDeviceDesktop());
67
- setPageWidth(innerWidth);
68
- if (isDesktop) setDisplaySearchFilter(false);
69
- };
70
-
71
- window.addEventListener('resize', handleResize);
72
- return () => {
73
- window.removeEventListener('resize', handleResize);
74
- };
75
- },
76
- [isDesktop, pageWidth, setDisplaySearchFilter]
77
- );
78
-
79
56
  useEffect(
80
57
  () => {
81
58
  if (filterValues.shouldSearch) {
@@ -86,16 +63,9 @@ const SearchFilter = ({
86
63
  [filterValues, handleSubmit]
87
64
  );
88
65
 
89
- let isDesktopFormDisplayed = true;
90
- let isMobileFormDisplayed = false;
91
-
92
- if (!isDesktop && isCollapsedOnResponsive) {
93
- isMobileFormDisplayed = displaySearchFilter;
94
- isDesktopFormDisplayed = false;
95
- }
96
-
97
- const formClass = classnames({
98
- 'filter__form filter__form--mobile': isMobileFormDisplayed
66
+ const formClass = classnames('filter__form filter__form--initial', {
67
+ 'filter__form--mobile': isCollapsedOnResponsive && displaySearchFilter,
68
+ 'filter__form--collapsible': isCollapsedOnResponsive
99
69
  });
100
70
 
101
71
  const {
@@ -122,143 +92,138 @@ const SearchFilter = ({
122
92
 
123
93
  return (
124
94
  <>
125
- {isDesktopFormDisplayed || isMobileFormDisplayed ? (
126
- <form
127
- ref={searchFilterRef}
128
- className={formClass}
129
- data-testid={formId}
130
- id={formId}
131
- onSubmit={e => {
132
- e.preventDefault();
133
- const newQuery = buildQuery(filterValues, filters);
134
- handleSearch(newQuery);
135
- }}>
136
- {isMobileFormDisplayed && (
137
- <CloseMobileForm handleClose={() => setDisplaySearchFilter(false)} />
138
- )}
139
-
140
- <div className="filter filter--search-refine">
141
- {isDesktopFormDisplayed && <ResetDesktopForm handleReset={handleReset} />}
142
-
143
- <div className="filter__wrapper filter__wrapper--search-refine">
144
- {!shouldGroup && (
95
+ <form
96
+ ref={searchFilterRef}
97
+ className={formClass}
98
+ data-testid={formId}
99
+ id={formId}
100
+ onSubmit={e => {
101
+ e.preventDefault();
102
+ const newQuery = buildQuery(filterValues, filters);
103
+ handleSearch(newQuery);
104
+ }}>
105
+ {displaySearchFilter && (
106
+ <CloseMobileForm handleClose={() => setDisplaySearchFilter(false)} />
107
+ )}
108
+
109
+ <div className="filter filter--search-refine">
110
+ <ResetDesktopForm handleReset={handleReset} />
111
+
112
+ <div className="filter__wrapper filter__wrapper--search-refine">
113
+ {!shouldGroup && (
114
+ <FiltersList
115
+ shouldSearch={shouldSearch}
116
+ data={data}
117
+ filters={filters}
118
+ hasUrl={hasUrl}
119
+ entity={entity}
120
+ filterValues={filterValues}
121
+ updateFilterValues={updateFilterValues}
122
+ />
123
+ )}
124
+
125
+ {shouldGroup && (
126
+ <>
145
127
  <FiltersList
146
128
  shouldSearch={shouldSearch}
147
129
  data={data}
148
- filters={filters}
130
+ filters={filters.slice(0, groupAfterMobile)}
149
131
  hasUrl={hasUrl}
150
132
  entity={entity}
151
133
  filterValues={filterValues}
152
134
  updateFilterValues={updateFilterValues}
153
135
  />
154
- )}
155
-
156
- {shouldGroup && (
157
- <>
158
- <FiltersList
159
- shouldSearch={shouldSearch}
160
- data={data}
161
- filters={filters.slice(0, groupAfterMobile)}
162
- hasUrl={hasUrl}
163
- entity={entity}
164
- filterValues={filterValues}
165
- updateFilterValues={updateFilterValues}
166
- />
167
136
 
168
- {!!groupAfterMobile && (
169
- <button
170
- className={moreFiltersMobileTogglerClass}
171
- type="button"
172
- onClick={() => setMoreFiltersMobileCollapsed(!moreFiltersMobileCollapsed)}>
173
- Filters
174
- </button>
175
- )}
176
-
177
- <div className={moreFiltersMobileWrapperClass}>
178
- <div className={MORE_FILTERS_CLASSES.MOBILE_CONTENT}>
179
- <FiltersList
180
- shouldSearch={shouldSearch && isDeviceDesktop()}
181
- data={data}
182
- filters={filters.slice(
183
- groupAfterMobile,
184
- groupAfterDesktop ? groupAfterDesktop - 1 : 0
185
- )}
186
- hasUrl={hasUrl}
187
- entity={entity}
188
- filterValues={filterValues}
189
- updateFilterValues={updateFilterValues}
190
- />
191
-
192
- {!!groupAfterDesktop && (
193
- <button
194
- className={moreFiltersDesktopTogglerClass}
195
- type="button"
196
- onClick={() =>
197
- setMoreFiltersDesktopCollapsed(!moreFiltersDesktopCollapsed)
198
- }>
199
- More filters
200
- </button>
137
+ {!!groupAfterMobile && (
138
+ <button
139
+ className={moreFiltersMobileTogglerClass}
140
+ type="button"
141
+ onClick={() => setMoreFiltersMobileCollapsed(!moreFiltersMobileCollapsed)}>
142
+ Filters
143
+ </button>
144
+ )}
145
+
146
+ <div className={moreFiltersMobileWrapperClass}>
147
+ <div className={MORE_FILTERS_CLASSES.MOBILE_CONTENT}>
148
+ <FiltersList
149
+ shouldSearch={shouldSearch && isDeviceDesktop()}
150
+ data={data}
151
+ filters={filters.slice(
152
+ groupAfterMobile,
153
+ groupAfterDesktop ? groupAfterDesktop - 1 : 0
201
154
  )}
155
+ hasUrl={hasUrl}
156
+ entity={entity}
157
+ filterValues={filterValues}
158
+ updateFilterValues={updateFilterValues}
159
+ />
160
+
161
+ {!!groupAfterDesktop && (
162
+ <button
163
+ className={moreFiltersDesktopTogglerClass}
164
+ type="button"
165
+ onClick={() =>
166
+ setMoreFiltersDesktopCollapsed(!moreFiltersDesktopCollapsed)
167
+ }>
168
+ More filters
169
+ </button>
170
+ )}
171
+
172
+ <div className={moreFiltersDesktopWrapperClass}>
173
+ <div className={MORE_FILTERS_CLASSES.DESKTOP_CONTENT}>
174
+ <FiltersList
175
+ shouldSearch={false}
176
+ data={data}
177
+ filters={filters.slice(groupAfterDesktop)}
178
+ hasUrl={hasUrl}
179
+ entity={entity}
180
+ filterValues={filterValues}
181
+ updateFilterValues={updateFilterValues}
182
+ />
183
+ </div>
202
184
 
203
- <div className={moreFiltersDesktopWrapperClass}>
204
- <div className={MORE_FILTERS_CLASSES.DESKTOP_CONTENT}>
205
- <FiltersList
206
- shouldSearch={false}
207
- data={data}
208
- filters={filters.slice(groupAfterDesktop)}
209
- hasUrl={hasUrl}
210
- entity={entity}
211
- filterValues={filterValues}
212
- updateFilterValues={updateFilterValues}
213
- />
214
- </div>
215
-
216
- <div className={MORE_FILTERS_CLASSES.DESKTOP_BUTTONS}>
217
- <ResetDesktopForm handleReset={handleReset} />
185
+ <div className={MORE_FILTERS_CLASSES.DESKTOP_BUTTONS}>
186
+ <ResetDesktopForm handleReset={handleReset} />
218
187
 
219
- <button className="button button--full-width" type="submit">
220
- {SEARCH}
221
- </button>
222
- </div>
188
+ <button className="button button--full-width" type="submit">
189
+ {SEARCH}
190
+ </button>
223
191
  </div>
224
192
  </div>
193
+ </div>
225
194
 
226
- <div className={MORE_FILTERS_CLASSES.MOBILE_BUTTONS}>
227
- <ResetDesktopForm handleReset={handleReset} />
195
+ <div className={MORE_FILTERS_CLASSES.MOBILE_BUTTONS}>
196
+ <ResetDesktopForm handleReset={handleReset} />
228
197
 
229
- <button className="button button--full-width" type="submit">
230
- {SEARCH}
231
- </button>
232
- </div>
198
+ <button className="button button--full-width" type="submit">
199
+ {SEARCH}
200
+ </button>
233
201
  </div>
234
- </>
235
- )}
202
+ </div>
203
+ </>
204
+ )}
236
205
 
237
- <br />
206
+ <br />
238
207
 
239
- {isDesktopFormDisplayed && (
240
- <button className="button button--full-width" type="submit">
241
- {SEARCH}
242
- </button>
243
- )}
244
- </div>
208
+ {!displaySearchFilter && (
209
+ <button className="button button--full-width" type="submit">
210
+ {SEARCH}
211
+ </button>
212
+ )}
245
213
  </div>
214
+ </div>
215
+
216
+ {displaySearchFilter && <MobileFormToolbar formId={formId} handleReset={handleReset} />}
217
+ </form>
246
218
 
247
- {isMobileFormDisplayed && <MobileFormToolbar formId={formId} handleReset={handleReset} />}
248
- </form>
249
- ) : (
250
- <>
251
- {isCollapsedOnResponsive && (
252
- <div
253
- className="filter__refine filter__refine--mobile-close"
254
- data-testid="refine-mobile">
255
- <div role="button" onClick={() => setDisplaySearchFilter(true)}>
256
- {REFINE}
257
- </div>
219
+ {isCollapsedOnResponsive &&
220
+ !displaySearchFilter && (
221
+ <div className="filter__refine filter__refine--mobile-close" data-testid="refine-mobile">
222
+ <div role="button" onClick={() => setDisplaySearchFilter(true)}>
223
+ {REFINE}
258
224
  </div>
259
- )}
260
- </>
261
- )}
225
+ </div>
226
+ )}
262
227
  </>
263
228
  );
264
229
  };
@@ -4,7 +4,15 @@ import Select from '@blaze-react/select';
4
4
  import { withTitle } from '../../../HOC';
5
5
  import { DEFAULT_OPTION } from '../constants';
6
6
 
7
- const SelectFilter = ({ data, label, prop, updateFilterValues, filterValues, shouldSearch }) => {
7
+ const SelectFilter = ({
8
+ data,
9
+ label,
10
+ prop,
11
+ updateFilterValues,
12
+ filterValues,
13
+ shouldSearch,
14
+ displayLabelAsPlaceholder
15
+ }) => {
8
16
  const filterValue = filterValues[prop] || '';
9
17
 
10
18
  const options = data[prop].buckets
@@ -12,16 +20,29 @@ const SelectFilter = ({ data, label, prop, updateFilterValues, filterValues, sho
12
20
  .filter(Boolean)
13
21
  .sort();
14
22
 
15
- const optionsJoined = [DEFAULT_OPTION, ...options];
23
+ const optionsJoined = options;
24
+
25
+ const labelText = label || prop;
26
+ let labelToUse = labelText;
27
+ let defaultTextValue = DEFAULT_OPTION;
28
+ if (displayLabelAsPlaceholder) {
29
+ defaultTextValue = labelToUse;
30
+ labelToUse = null;
31
+ }
16
32
 
17
33
  return (
18
34
  <Select
19
- label={`${label || prop}`}
35
+ label={labelToUse}
20
36
  value={filterValue}
21
37
  id={prop}
38
+ data-testid={`filter-${prop}`}
22
39
  options={optionsJoined}
40
+ defaultTextValue={defaultTextValue}
23
41
  onChange={({ value }) => {
24
- updateFilterValues({ [prop]: value }, shouldSearch);
42
+ let valueToUse = value;
43
+ if (value === defaultTextValue) valueToUse = '';
44
+
45
+ updateFilterValues({ [prop]: valueToUse }, shouldSearch);
25
46
  }}
26
47
  />
27
48
  );
@@ -33,12 +54,14 @@ SelectFilter.propTypes = {
33
54
  filterValues: PropTypes.object.isRequired,
34
55
  updateFilterValues: PropTypes.func.isRequired,
35
56
  shouldSearch: PropTypes.bool,
36
- label: PropTypes.string
57
+ label: PropTypes.string,
58
+ displayLabelAsPlaceholder: PropTypes.bool
37
59
  };
38
60
 
39
61
  SelectFilter.defaultProps = {
40
62
  shouldSearch: false,
41
- label: ''
63
+ label: '',
64
+ displayLabelAsPlaceholder: false
42
65
  };
43
66
 
44
67
  export default withTitle(SelectFilter);