@ndla/ui 23.0.0 → 24.0.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 (95) hide show
  1. package/es/Article/ArticleAuthorContent.js +2 -4
  2. package/es/AuthorInfo/AuthorInfo.js +29 -16
  3. package/es/ContentCard/ContentCard.js +66 -25
  4. package/es/FileList/File.js +34 -8
  5. package/es/FileList/FileList.js +29 -3
  6. package/es/InfoBox/InfoBox.js +10 -3
  7. package/es/InfoWidget/InfoWidget.js +67 -22
  8. package/es/Portrait/Portrait.js +19 -13
  9. package/es/Search/ActiveFilterContent.js +4 -14
  10. package/es/Search/ActiveFilters.js +8 -19
  11. package/es/Search/SearchField.js +31 -52
  12. package/es/Search/SearchResult.js +113 -136
  13. package/es/Search/ToggleSearchButton.js +34 -43
  14. package/es/Search/index.js +2 -8
  15. package/es/all.css +1 -1
  16. package/es/index-javascript.js +0 -1
  17. package/es/index.js +2 -1
  18. package/lib/Article/ArticleAuthorContent.js +9 -4
  19. package/lib/AuthorInfo/AuthorInfo.d.ts +1 -11
  20. package/lib/AuthorInfo/AuthorInfo.js +36 -20
  21. package/lib/ContentCard/ContentCard.d.ts +1 -15
  22. package/lib/ContentCard/ContentCard.js +60 -28
  23. package/lib/FileList/File.js +36 -12
  24. package/lib/FileList/FileList.js +28 -5
  25. package/lib/InfoBox/InfoBox.js +11 -4
  26. package/lib/InfoWidget/InfoWidget.js +61 -25
  27. package/lib/Portrait/Portrait.js +19 -14
  28. package/lib/Search/ActiveFilterContent.d.ts +13 -0
  29. package/lib/Search/ActiveFilterContent.js +4 -15
  30. package/lib/Search/ActiveFilters.d.ts +13 -0
  31. package/lib/Search/ActiveFilters.js +8 -20
  32. package/lib/Search/SearchField.d.ts +19 -0
  33. package/lib/Search/SearchField.js +32 -56
  34. package/lib/Search/SearchResult.d.ts +36 -0
  35. package/lib/Search/SearchResult.js +116 -159
  36. package/lib/Search/ToggleSearchButton.d.ts +16 -0
  37. package/lib/Search/ToggleSearchButton.js +36 -46
  38. package/lib/Search/index.d.ts +12 -0
  39. package/lib/Search/index.js +0 -54
  40. package/lib/SearchTypeResult/SearchTypeHeader.d.ts +1 -1
  41. package/lib/all.css +1 -1
  42. package/lib/index-javascript.js +0 -74
  43. package/lib/index.d.ts +1 -0
  44. package/lib/index.js +38 -1
  45. package/package.json +5 -5
  46. package/src/Article/ArticleAuthorContent.tsx +1 -1
  47. package/src/AuthorInfo/AuthorInfo.tsx +53 -19
  48. package/src/ContentCard/ContentCard.tsx +127 -35
  49. package/src/FileList/File.tsx +47 -17
  50. package/src/FileList/FileList.tsx +37 -8
  51. package/src/InfoBox/InfoBox.tsx +24 -4
  52. package/src/InfoWidget/InfoWidget.tsx +83 -34
  53. package/src/Portrait/Portrait.tsx +25 -10
  54. package/src/Search/{ActiveFilterContent.jsx → ActiveFilterContent.tsx} +11 -12
  55. package/src/Search/{ActiveFilters.jsx → ActiveFilters.tsx} +20 -17
  56. package/src/Search/{SearchField.jsx → SearchField.tsx} +58 -68
  57. package/src/Search/SearchResult.tsx +360 -0
  58. package/src/Search/ToggleSearchButton.tsx +73 -0
  59. package/src/Search/component.search.scss +0 -4
  60. package/src/Search/index.ts +16 -0
  61. package/src/all.scss +0 -1
  62. package/src/index-javascript.js +0 -15
  63. package/src/index.ts +2 -0
  64. package/src/main.scss +0 -6
  65. package/es/Search/SearchFilter.js +0 -72
  66. package/es/Search/SearchFilterList.js +0 -115
  67. package/es/Search/SearchOverlay.js +0 -39
  68. package/es/Search/SearchPage.js +0 -178
  69. package/es/Search/SearchPopoverFilter.js +0 -152
  70. package/es/Search/SearchResultAuthor.js +0 -51
  71. package/lib/Search/SearchFilter.js +0 -88
  72. package/lib/Search/SearchFilterList.js +0 -137
  73. package/lib/Search/SearchOverlay.js +0 -62
  74. package/lib/Search/SearchPage.js +0 -207
  75. package/lib/Search/SearchPopoverFilter.js +0 -172
  76. package/lib/Search/SearchResultAuthor.js +0 -60
  77. package/src/AuthorInfo/component.author-info.scss +0 -54
  78. package/src/ContentCard/component.content-card.scss +0 -109
  79. package/src/FileList/component.file-list.scss +0 -102
  80. package/src/InfoBox/component.info-box.scss +0 -21
  81. package/src/InfoWidget/component.info-widget.scss +0 -52
  82. package/src/Portrait/component.portrait.scss +0 -29
  83. package/src/Search/SearchFilter.jsx +0 -82
  84. package/src/Search/SearchFilterList.jsx +0 -110
  85. package/src/Search/SearchOverlay.jsx +0 -38
  86. package/src/Search/SearchPage.jsx +0 -178
  87. package/src/Search/SearchPopoverFilter.jsx +0 -109
  88. package/src/Search/SearchResult.jsx +0 -239
  89. package/src/Search/SearchResultAuthor.jsx +0 -54
  90. package/src/Search/ToggleSearchButton.jsx +0 -64
  91. package/src/Search/component.search-filter.scss +0 -67
  92. package/src/Search/component.search-overlay.scss +0 -103
  93. package/src/Search/component.search-page.scss +0 -125
  94. package/src/Search/component.search-result-author.scss +0 -65
  95. package/src/Search/index.js +0 -34
@@ -1,102 +0,0 @@
1
- .c-file-list {
2
- margin: $spacing--large 0;
3
- padding: $spacing--small 0 $spacing $spacing;
4
- border-left: 2px solid $brand-grey--lightest;
5
- font-family: $font;
6
-
7
- &__heading {
8
- @include font-size(16px, 18px);
9
- letter-spacing: 0.05em;
10
- margin: 0 0 $spacing--small / 2 0;
11
- padding-bottom: $spacing--small / 2;
12
-
13
- border-bottom: 2px solid $brand-grey--light;
14
- font-weight: $font-weight-bold;
15
- text-transform: uppercase;
16
- }
17
-
18
- &__files {
19
- margin: 0;
20
- padding: 0;
21
- }
22
-
23
- &__item {
24
- @include font-size(18px, 26px);
25
- font-weight: $font-weight-semibold;
26
- min-height: 60px;
27
- background: $brand-grey--lighter;
28
- display: flex;
29
- align-items: center;
30
- flex-wrap: wrap;
31
- margin-bottom: $spacing--small / 2;
32
- padding: $spacing--small;
33
-
34
- @include mq(tablet) {
35
- padding: $spacing--small $spacing;
36
- }
37
- }
38
-
39
- &__link {
40
- box-shadow: none;
41
- position: relative;
42
- color: $brand-color;
43
- margin-right: $spacing;
44
- display: flex;
45
- align-items: center;
46
-
47
- &:last-child {
48
- margin-right: 0;
49
- }
50
-
51
- &:hover,
52
- &:focus,
53
- &:active {
54
- .c-file-list__link-text {
55
- & > span {
56
- box-shadow: $link--hover;
57
- }
58
- }
59
- }
60
- }
61
-
62
- &__link-text {
63
- & > span {
64
- box-shadow: $link;
65
- }
66
- }
67
-
68
- &__tooltip {
69
- position: absolute;
70
- display: none;
71
- left: 50%;
72
- top: -$spacing--small;
73
- transform: translate3d(-50%, -100%, 0);
74
- width: 300px;
75
- text-align: center;
76
- z-index: 1;
77
-
78
- &[aria-hidden='false'] {
79
- display: block;
80
- animation-name: fadeIn;
81
- animation-duration: 0.3s;
82
- }
83
- }
84
-
85
- &__tooltip-text {
86
- display: inline-block;
87
- text-align: left;
88
- background: $brand-color;
89
- padding: $spacing--small;
90
- @include font-size(14px, 18px);
91
- font-weight: $font-weight-normal;
92
- color: $white;
93
- }
94
-
95
- .c-icon {
96
- margin-top: 3px;
97
- flex-shrink: 0;
98
- margin-right: $spacing--small;
99
- height: 18px;
100
- width: 18px;
101
- }
102
- }
@@ -1,21 +0,0 @@
1
- .c-info-box {
2
- background: $yellow-light;
3
- padding: $spacing--small $spacing;
4
- font-family: $font;
5
- @include font-size(14px, 18px);
6
-
7
- margin-bottom: $spacing--medium;
8
-
9
- @include mq(tablet) {
10
- @include font-size(16px, 20px);
11
- padding: $spacing;
12
- }
13
-
14
- & > *:first-child {
15
- margin-top: 0;
16
- }
17
-
18
- & > *:last-child {
19
- margin-bottom: 0;
20
- }
21
- }
@@ -1,52 +0,0 @@
1
- .c-info-widget {
2
- max-width: 600px;
3
-
4
- &--center {
5
- margin: 0 auto;
6
- }
7
-
8
- &__description {
9
- padding: $spacing;
10
- background: $brand-color--lighter;
11
- color: $brand-color--dark;
12
- @include font-size(18px, 26px);
13
-
14
- p {
15
- margin-top: 0;
16
-
17
- &:last-child {
18
- margin-bottom: 0;
19
- }
20
- }
21
- }
22
-
23
- &__links {
24
- display: flex;
25
- align-items: center;
26
- justify-content: flex-end;
27
- }
28
-
29
- &__main-link {
30
- color: $brand-color--dark;
31
- @include font-size(16px, 24px);
32
- }
33
-
34
- &__icon-link {
35
- width: 47px;
36
- height: 47px;
37
- border-radius: 100%;
38
- background: $brand-color--lighter;
39
- color: $brand-color--dark;
40
- box-shadow: none;
41
- display: flex;
42
- justify-content: center;
43
- align-items: center;
44
-
45
- .c-icon {
46
- width: 20px;
47
- height: 20px;
48
- }
49
-
50
- margin-right: $spacing--small;
51
- }
52
- }
@@ -1,29 +0,0 @@
1
- .c-portrait {
2
- width: 7rem;
3
- height: 7rem;
4
- span {
5
- display: block;
6
- border-radius: 50%;
7
- background-color: rgba(0,0,0,0.16);
8
- background-size: cover;
9
- background-position: center center;
10
- width: 7rem;
11
- height: 7rem;
12
- }
13
- &--small {
14
- width: 4rem;
15
- height: 4rem;
16
- span {
17
- width: 4rem;
18
- height: 4rem;
19
- }
20
- }
21
- &--large {
22
- width: 10rem;
23
- height: 10rem;
24
- span {
25
- width: 10rem;
26
- height: 10rem;
27
- }
28
- }
29
- }
@@ -1,82 +0,0 @@
1
- import React from 'react';
2
- import BEMHelper from 'react-bem-helper';
3
- import PropTypes from 'prop-types';
4
-
5
- import { FilterList } from '../Filter';
6
-
7
- const searchFilterClasses = BEMHelper({
8
- prefix: 'c-',
9
- name: 'search-filter',
10
- outputIsString: true,
11
- });
12
-
13
- const valueShape = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
14
-
15
- const SearchFilter = ({
16
- label,
17
- options,
18
- values,
19
- defaultVisibleCount,
20
- showLabel,
21
- hideLabel,
22
- narrowScreenOnly,
23
- contextFilter,
24
- onChange,
25
- noFilterSelectedLabel,
26
- children,
27
- }) => {
28
- const modifiers = [];
29
-
30
- if (narrowScreenOnly) {
31
- modifiers.push('narrow-screen-only');
32
- }
33
-
34
- if (contextFilter) {
35
- modifiers.push('context-filter');
36
- }
37
-
38
- return (
39
- <div className={searchFilterClasses('', modifiers)}>
40
- <FilterList
41
- options={options}
42
- label={label}
43
- labelNotVisible={contextFilter}
44
- values={values}
45
- defaultVisibleCount={defaultVisibleCount}
46
- modifiers={!contextFilter ? 'search' : null}
47
- showLabel={showLabel}
48
- hideLabel={hideLabel}
49
- onChange={onChange}
50
- alignedGroup
51
- noFilterSelectedLabel={noFilterSelectedLabel}
52
- />
53
- {children}
54
- </div>
55
- );
56
- };
57
-
58
- SearchFilter.propTypes = {
59
- label: PropTypes.string.isRequired,
60
- options: PropTypes.arrayOf(
61
- PropTypes.shape({
62
- value: valueShape.isRequired,
63
- title: PropTypes.string.isRequired,
64
- noResults: PropTypes.bool,
65
- }),
66
- ).isRequired,
67
- values: PropTypes.arrayOf(valueShape),
68
- defaultVisibleCount: PropTypes.number,
69
- onChange: PropTypes.func,
70
- showLabel: PropTypes.string,
71
- hideLabel: PropTypes.string,
72
- narrowScreenOnly: PropTypes.bool,
73
- noFilterSelectedLabel: PropTypes.string,
74
- contextFilter: PropTypes.bool,
75
- children: PropTypes.node,
76
- };
77
-
78
- SearchFilter.defaultProps = {
79
- values: [],
80
- };
81
-
82
- export default SearchFilter;
@@ -1,110 +0,0 @@
1
- import React, { Fragment } from 'react';
2
- import BEMHelper from 'react-bem-helper';
3
- import PropTypes from 'prop-types';
4
-
5
- import { FilterList, ToggleItem } from '../Filter';
6
-
7
- const searchFilterClasses = BEMHelper({
8
- prefix: 'c-',
9
- name: 'search-filter',
10
- outputIsString: true,
11
- });
12
-
13
- const valueShape = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
14
-
15
- const SearchFilterList = ({
16
- label,
17
- options,
18
- values,
19
- narrowScreenOnly,
20
- onChange,
21
- onSubfilterChange,
22
- preid,
23
- noFilterSelectedLabel,
24
- subjectValues,
25
- children,
26
- }) => {
27
- return (
28
- <div className={searchFilterClasses('')}>
29
- <div>
30
- {options.map((option, index) => {
31
- const itemModifiers = [];
32
- const checked = values.some((value) => value === option.value);
33
-
34
- if (!checked && index + 1 > this.state.visibleCount) {
35
- itemModifiers.push('hidden');
36
- }
37
-
38
- const disabled = option.noResults || option.hits === 0;
39
-
40
- if (disabled) {
41
- itemModifiers.push('no-results');
42
- }
43
-
44
- return (
45
- <Fragment key={option.value}>
46
- <ToggleItem
47
- modifiers={itemModifiers}
48
- id={preid + option.value}
49
- value={option.value}
50
- disabled={disabled}
51
- tabIndex={disabled ? -1 : 0}
52
- checked={checked}
53
- icon={option.icon}
54
- label={option.title}
55
- component="div"
56
- onChange={(event) => {
57
- let newValues = null;
58
- if (event.currentTarget.checked) {
59
- newValues = [...values, option.value];
60
- } else {
61
- newValues = values.filter((value) => value !== option.value);
62
- }
63
- if (onChange) {
64
- onChange(newValues, option.value);
65
- }
66
- }}
67
- />
68
- <div className={searchFilterClasses()}>
69
- <FilterList
70
- options={option.subjectFilters}
71
- label={label}
72
- labelNotVisible
73
- values={subjectValues[option.value]}
74
- onChange={(subjectFilters, subjectFilter) =>
75
- onSubfilterChange(option.value, subjectFilters, subjectFilter)
76
- }
77
- alignedGroup
78
- noFilterSelectedLabel={noFilterSelectedLabel}
79
- />
80
- </div>
81
- </Fragment>
82
- );
83
- })}
84
- </div>
85
- {children}
86
- </div>
87
- );
88
- };
89
-
90
- SearchFilterList.propTypes = {
91
- label: PropTypes.string.isRequired,
92
- options: PropTypes.arrayOf(
93
- PropTypes.shape({
94
- value: valueShape.isRequired,
95
- title: PropTypes.string.isRequired,
96
- noResults: PropTypes.bool,
97
- }),
98
- ).isRequired,
99
- values: PropTypes.arrayOf(valueShape),
100
- onChange: PropTypes.func,
101
- onSubfilterChange: PropTypes.func,
102
- noFilterSelectedLabel: PropTypes.string,
103
- children: PropTypes.node,
104
- };
105
-
106
- SearchFilterList.defaultProps = {
107
- values: [],
108
- };
109
-
110
- export default SearchFilterList;
@@ -1,38 +0,0 @@
1
- import React, { Fragment } from 'react';
2
- import PropTypes from 'prop-types';
3
- import BEMHelper from 'react-bem-helper';
4
- import { Cross } from '@ndla/icons/action';
5
- import { CSSTransition } from 'react-transition-group';
6
-
7
- import Fade from '../Animation/Fade';
8
-
9
- const classes = BEMHelper({
10
- prefix: 'c-',
11
- name: 'search-overlay',
12
- });
13
-
14
- const SearchOverlay = ({ close, isOpen, children }) => (
15
- <Fragment>
16
- <Fade in={isOpen}>
17
- <div className="o-backdrop" />
18
- </Fade>
19
- <CSSTransition timeout={300} classNames={classes().className} unmountOnExit in={isOpen}>
20
- <div {...classes()}>
21
- <div {...classes('container o-wrapper')}>
22
- {children}
23
- <button {...classes('close-button')} type="button" onClick={close}>
24
- <Cross />
25
- </button>
26
- </div>
27
- </div>
28
- </CSSTransition>
29
- </Fragment>
30
- );
31
-
32
- SearchOverlay.propTypes = {
33
- isOpen: PropTypes.bool.isRequired,
34
- close: PropTypes.func,
35
- children: PropTypes.node.isRequired,
36
- };
37
-
38
- export default SearchOverlay;
@@ -1,178 +0,0 @@
1
- import React, { Component, Fragment, createRef } from 'react';
2
- import BEMHelper from 'react-bem-helper';
3
- import PropTypes from 'prop-types';
4
- import { Back } from '@ndla/icons/common';
5
- import { debounce } from 'lodash';
6
- import { getCurrentBreakpoint, breakpoints } from '@ndla/util';
7
- import Modal, { ModalHeader, ModalBody, ModalCloseButton } from '@ndla/modal';
8
- import Button from '@ndla/button';
9
- import { withTranslation } from 'react-i18next';
10
-
11
- import SearchField from './SearchField';
12
- import ActiveFilters from './ActiveFilters';
13
- import { SearchFieldForm } from './SearchFieldForm';
14
-
15
- const classes = BEMHelper('c-search-page');
16
- const filterClasses = BEMHelper('c-filter');
17
-
18
- class SearchPage extends Component {
19
- constructor(props) {
20
- super(props);
21
- this.state = {
22
- isNarrowScreen: false,
23
- };
24
-
25
- this.filterCloseButton = null;
26
- this.inputRef = createRef();
27
- this.checkScreenSize = this.checkScreenSize.bind(this);
28
- this.checkScreenSizeDebounce = debounce(() => this.checkScreenSize(), 100);
29
- }
30
-
31
- componentDidMount() {
32
- window.addEventListener('resize', this.checkScreenSizeDebounce);
33
- this.checkScreenSize();
34
- }
35
-
36
- componentWillUnmount() {
37
- window.removeEventListener('resize', this.checkScreenSizeDebounce);
38
- }
39
-
40
- checkScreenSize() {
41
- const currentBreakpoint = getCurrentBreakpoint();
42
- const isNarrowScreen = currentBreakpoint === breakpoints.mobile || currentBreakpoint === breakpoints.tablet;
43
-
44
- /* eslint react/no-did-mount-set-state: 0 */
45
- if (isNarrowScreen !== this.state.isNarrowScreen) {
46
- this.setState({
47
- isNarrowScreen,
48
- });
49
- }
50
- }
51
-
52
- render() {
53
- const {
54
- searchString,
55
- onSearchFieldChange,
56
- onSearchFieldFilterRemove,
57
- searchFieldFilters,
58
- onSearch,
59
- // only on narrow screen
60
- activeFilters,
61
- resourceToLinkProps,
62
- filters,
63
- children,
64
- messages,
65
- author,
66
- t,
67
- } = this.props;
68
-
69
- return (
70
- <main {...classes()}>
71
- <div {...classes('search-field-wrapper')}>
72
- <SearchFieldForm onSubmit={onSearch}>
73
- <SearchField
74
- inputRef={this.inputRef}
75
- value={searchString}
76
- onChange={onSearchFieldChange}
77
- placeholder={t('searchPage.searchFieldPlaceholder')}
78
- filters={searchFieldFilters}
79
- onFilterRemove={onSearchFieldFilterRemove}
80
- resourceToLinkProps={resourceToLinkProps}
81
- messages={{
82
- searchFieldTitle: t('searchPage.search'),
83
- }}
84
- />
85
- </SearchFieldForm>
86
- </div>
87
- {author}
88
- <div {...classes('filter-result-wrapper')}>
89
- <aside {...classes('filter-wrapper')}>
90
- <h1 {...classes('filter-heading')}>{t('searchPage.searchPageMessages.filterHeading')}</h1>
91
- <div {...classes('filters')}>{!this.state.isNarrowScreen && filters}</div>
92
- </aside>
93
- <div {...classes('result-wrapper')}>
94
- <div {...classes('active-filters')}>
95
- <ActiveFilters
96
- filters={activeFilters}
97
- showOnSmallScreen
98
- onFilterRemove={(value, filterName) => onSearchFieldFilterRemove(value, filterName)}
99
- />
100
- </div>
101
- <div {...classes('toggle-filter')}>
102
- <Modal
103
- animation="subtle"
104
- animationDuration={150}
105
- size="fullscreen"
106
- backgroundColor="grey"
107
- activateButton={<Button outline>{t('searchPage.searchPageMessages.filterHeading')}</Button>}>
108
- {(onClose) => (
109
- <Fragment>
110
- <ModalHeader modifier="white left-align">
111
- <ModalCloseButton
112
- title={
113
- <Fragment>
114
- <Back /> {messages.narrowScreenFilterHeading}
115
- </Fragment>
116
- }
117
- onClick={onClose}>
118
- Close
119
- </ModalCloseButton>
120
- </ModalHeader>
121
- <ModalBody modifier="slide-in-left no-side-padding-mobile">
122
- {filters}
123
- <div {...filterClasses('usefilter-wrapper')}>
124
- <Button outline onClick={onClose}>
125
- {t('searchPage.searchFilterMessages.useFilter')}
126
- </Button>
127
- </div>
128
- </ModalBody>
129
- </Fragment>
130
- )}
131
- </Modal>
132
- </div>
133
-
134
- {children}
135
- </div>
136
- </div>
137
- </main>
138
- );
139
- }
140
- }
141
-
142
- SearchPage.propTypes = {
143
- // should be <Fragment />
144
- filters: PropTypes.node.isRequired,
145
- children: PropTypes.node.isRequired,
146
- searchString: PropTypes.string.isRequired,
147
- onSearchFieldChange: PropTypes.func.isRequired,
148
- onSearch: PropTypes.func.isRequired,
149
- onSearchFieldFilterRemove: PropTypes.func.isRequired,
150
- resourceToLinkProps: PropTypes.func.isRequired,
151
- searchFieldFilters: PropTypes.arrayOf(
152
- PropTypes.shape({
153
- value: PropTypes.string.isRequired,
154
- title: PropTypes.string.isRequired,
155
- filterName: PropTypes.string.isRequired,
156
- }),
157
- ),
158
- activeFilters: PropTypes.arrayOf(
159
- PropTypes.shape({
160
- value: PropTypes.string.isRequired,
161
- title: PropTypes.string.isRequired,
162
- filterName: PropTypes.string.isRequired,
163
- }),
164
- ),
165
- messages: PropTypes.shape({
166
- narrowScreenFilterHeading: PropTypes.string.isRequired,
167
- }).isRequired,
168
- author: PropTypes.node,
169
- hideResultText: PropTypes.bool,
170
- filterScreenChange: PropTypes.func,
171
- t: PropTypes.func.isRequired,
172
- };
173
-
174
- SearchPage.defaultProps = {
175
- author: null,
176
- };
177
-
178
- export default withTranslation()(SearchPage);