@plone/volto 18.0.0-alpha.32 → 18.0.0-alpha.33

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 (61) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/locales/ca/LC_MESSAGES/volto.po +12 -0
  3. package/locales/ca.json +1 -1
  4. package/locales/de/LC_MESSAGES/volto.po +12 -0
  5. package/locales/de.json +1 -1
  6. package/locales/en/LC_MESSAGES/volto.po +12 -0
  7. package/locales/en.json +1 -1
  8. package/locales/es/LC_MESSAGES/volto.po +12 -0
  9. package/locales/es.json +1 -1
  10. package/locales/eu/LC_MESSAGES/volto.po +12 -0
  11. package/locales/eu.json +1 -1
  12. package/locales/fi/LC_MESSAGES/volto.po +12 -0
  13. package/locales/fi.json +1 -1
  14. package/locales/fr/LC_MESSAGES/volto.po +12 -0
  15. package/locales/fr.json +1 -1
  16. package/locales/hi/LC_MESSAGES/volto.po +12 -0
  17. package/locales/hi.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +12 -0
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +12 -0
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +12 -0
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +12 -0
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +12 -0
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +12 -0
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +13 -1
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +12 -0
  32. package/locales/zh_CN.json +1 -1
  33. package/package.json +6 -4
  34. package/razzle.config.js +49 -0
  35. package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +1 -0
  36. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +158 -65
  37. package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +125 -71
  38. package/src/components/manage/Widgets/IdWidget.jsx +138 -203
  39. package/src/components/manage/Widgets/TextWidget.jsx +92 -124
  40. package/src/components/manage/Widgets/TextWidget.stories.jsx +14 -3
  41. package/src/components/theme/App/App.jsx +5 -0
  42. package/src/components/theme/Footer/Footer.jsx +1 -0
  43. package/src/components/theme/Navigation/Navigation.jsx +1 -1
  44. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +3 -4
  45. package/src/components/theme/View/View.jsx +1 -1
  46. package/src/config/server.js +0 -1
  47. package/src/express-middleware/static.js +37 -19
  48. package/src/helpers/Html/Html.jsx +6 -8
  49. package/src/helpers/Slots/index.tsx +12 -5
  50. package/src/server.jsx +34 -36
  51. package/theme/themes/pastanaga/extras/objectbrowser-widget.less +83 -0
  52. package/theme/themes/pastanaga/extras/widgets.less +19 -0
  53. package/types/components/manage/Sidebar/ObjectBrowserNav.d.ts +2 -1
  54. package/types/components/manage/Widgets/IdWidget.d.ts +54 -2
  55. package/types/components/manage/Widgets/TextWidget.d.ts +54 -5
  56. package/types/components/manage/Widgets/TextWidget.stories.d.ts +13 -1
  57. package/types/components/manage/Widgets/index.d.ts +2 -2
  58. package/types/config/Widgets.d.ts +1 -1
  59. package/types/config/server.d.ts +0 -3
  60. package/types/helpers/Slots/index.d.ts +5 -3
  61. package/types/start-client.d.ts +1 -1
@@ -3,14 +3,13 @@
3
3
  * @module components/manage/Widgets/IdWidget
4
4
  */
5
5
 
6
- import React, { Component } from 'react';
6
+ import { useState, useEffect, useRef } from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { connect } from 'react-redux';
9
- import { compose } from 'redux';
8
+ import { useSelector, useDispatch } from 'react-redux';
10
9
  import { Input } from 'semantic-ui-react';
11
10
  import { compact, concat, keys, map, union, uniq } from 'lodash';
12
11
 
13
- import { defineMessages, injectIntl } from 'react-intl';
12
+ import { defineMessages, useIntl } from 'react-intl';
14
13
  import { Icon } from '@plone/volto/components';
15
14
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
16
15
  import config from '@plone/volto/registry';
@@ -28,222 +27,158 @@ const messages = defineMessages({
28
27
  },
29
28
  });
30
29
 
31
- /**
32
- * The id widget.
33
- *
34
- * This is the id widget to handle for example the short name field.
35
- */
36
- class IdWidget extends Component {
37
- /**
38
- * Property types.
39
- * @property {Object} propTypes Property types.
40
- * @static
41
- */
42
- static propTypes = {
43
- id: PropTypes.string.isRequired,
44
- title: PropTypes.string.isRequired,
45
- description: PropTypes.string,
46
- required: PropTypes.bool,
47
- error: PropTypes.arrayOf(PropTypes.string),
48
- value: PropTypes.string,
49
- focus: PropTypes.bool,
50
- onChange: PropTypes.func,
51
- onBlur: PropTypes.func,
52
- onClick: PropTypes.func,
53
- onEdit: PropTypes.func,
54
- onDelete: PropTypes.func,
55
- icon: PropTypes.shape({
56
- xmlns: PropTypes.string,
57
- viewBox: PropTypes.string,
58
- content: PropTypes.string,
59
- }),
60
- iconAction: PropTypes.func,
61
- minLength: PropTypes.number,
62
- maxLength: PropTypes.number,
63
- wrapped: PropTypes.bool,
64
- placeholder: PropTypes.string,
65
- };
66
-
67
- /**
68
- * Default properties.
69
- * @property {Object} defaultProps Default properties.
70
- * @static
71
- */
72
- static defaultProps = {
73
- description: null,
74
- required: false,
75
- error: [],
76
- value: null,
77
- onChange: () => {},
78
- onBlur: () => {},
79
- onClick: () => {},
80
- onEdit: null,
81
- onDelete: null,
82
- focus: false,
83
- icon: null,
84
- iconAction: null,
85
- minLength: null,
86
- maxLength: null,
87
- };
88
-
89
- /**
90
- * Constructor
91
- * @method constructor
92
- * @param {Object} props Component properties
93
- * @constructs Actions
94
- */
95
- constructor(props) {
96
- super(props);
97
- this.state = {
98
- error: [],
99
- reservedIds: compact(
100
- uniq(
101
- union(
102
- config.settings.reservedIds,
103
- map(config.settings.nonContentRoutes, (route) =>
104
- String(route).replace(/[^a-z-]/g, ''),
105
- ),
30
+ const IdWidget = (props) => {
31
+ const {
32
+ id,
33
+ onClick,
34
+ icon,
35
+ iconAction,
36
+ minLength,
37
+ maxLength,
38
+ onBlur,
39
+ value,
40
+ focus,
41
+ isDisabled,
42
+ placeholder,
43
+ onChange,
44
+ } = props;
45
+
46
+ const intl = useIntl();
47
+ const dispatch = useDispatch();
48
+ const ref = useRef();
49
+
50
+ const indexes = useSelector((state) => keys(state.querystring.indexes));
51
+
52
+ const [errors, setError] = useState([]);
53
+ const [reservedIds] = useState(
54
+ compact(
55
+ uniq(
56
+ union(
57
+ config.settings.reservedIds,
58
+ map(config.settings.nonContentRoutes, (route) =>
59
+ String(route).replace(/[^a-z-]/g, ''),
106
60
  ),
107
61
  ),
108
62
  ),
109
- };
110
-
111
- this.handleChange = this.handleChange.bind(this);
112
- this.handleBlur = this.handleBlur.bind(this);
113
- this.fieldValidation = this.fieldValidation.bind(this);
114
- }
115
-
116
- /**
117
- * Component did mount lifecycle method
118
- * @method componentDidMount
119
- * @returns {undefined}
120
- */
121
- componentDidMount() {
122
- if (this.props.focus) {
123
- this.node.focus();
124
- }
125
- this.props.getQuerystring();
126
- this.fieldValidation(this.props.value);
127
- }
128
-
129
- /**
130
- * Field validation.
131
- * @method fieldValidation
132
- * @param {string} value New value
133
- * @returns {undefined}
134
- */
135
- fieldValidation(value) {
63
+ ),
64
+ );
65
+ const fieldValidation = (values) => {
136
66
  const error = [];
137
67
 
138
68
  // Check reserved id's
139
- if (this.state.reservedIds.indexOf(value) !== -1) {
140
- error.push(this.props.intl.formatMessage(messages.reservedId));
69
+ if (reservedIds.indexOf(values) !== -1) {
70
+ error.push(intl.formatMessage(messages.reservedId));
141
71
  }
142
72
 
143
73
  // Check invalid characters
144
74
  if (
145
75
  // eslint-disable-next-line no-control-regex
146
76
  !/^(?!.*\\)(?!\+\+)(?!@@)(?!.*request)(?!.*contributors)(?!aq_)(?!.*__)(?!_)(?!((^|\/)\.\.?($|\/)|^"\s*"$))(?!.*[A-Z])(?:(?![\r\n<>/?&#\x00-\x1F\x7F])['\x00-\x7F\u0080-\uFFFF. _])*$/.test(
147
- value,
77
+ values,
148
78
  )
149
79
  ) {
150
- error.push(this.props.intl.formatMessage(messages.invalidCharacters));
80
+ error.push(intl.formatMessage(messages.invalidCharacters));
151
81
  }
152
82
 
153
83
  // Check indexes
154
- if (this.props.indexes.indexOf(value) !== -1) {
155
- error.push(this.props.intl.formatMessage(messages.reservedId));
84
+ if (indexes.indexOf(values) !== -1) {
85
+ error.push(intl.formatMessage(messages.reservedId));
156
86
  }
157
87
 
158
- this.setState({ error });
159
- }
160
-
161
- /**
162
- * Handle the field change.
163
- * @method handleChange
164
- * @param {Object} event Event object
165
- * @returns {undefined}
166
- */
167
- handleChange({ target }) {
168
- this.fieldValidation(target.value);
169
- this.props.onChange(
170
- this.props.id,
171
- target.value === '' ? undefined : target.value,
172
- );
173
- }
174
-
175
- /**
176
- * Handle the field blur.
177
- * @method handleBlur
178
- * @param {Object} event Event object
179
- * @returns {undefined}
180
- */
181
- handleBlur({ target }) {
182
- this.fieldValidation(target.value);
183
- this.props.onBlur(
184
- this.props.id,
185
- target.value === '' ? undefined : target.value,
186
- );
187
- }
188
-
189
- /**
190
- * Render method.
191
- * @method render
192
- * @returns {string} Markup for the component.
193
- */
194
- render() {
195
- const {
196
- id,
197
- value,
198
- onClick,
199
- icon,
200
- iconAction,
201
- minLength,
202
- maxLength,
203
- placeholder,
204
- } = this.props;
205
-
206
- const props = {
207
- ...this.props,
208
- error: concat(this.props.error, this.state.error),
209
- };
210
-
211
- return (
212
- <FormFieldWrapper {...props} className="text">
213
- <Input
214
- id={`field-${id}`}
215
- name={id}
216
- value={value || ''}
217
- disabled={this.props.isDisabled}
218
- icon={icon || null}
219
- placeholder={placeholder}
220
- onChange={this.handleChange}
221
- onBlur={this.handleBlur}
222
- onClick={() => onClick()}
223
- ref={(node) => {
224
- this.node = node;
225
- }}
226
- minLength={minLength || null}
227
- maxLength={maxLength || null}
228
- />
229
- {icon && iconAction && (
230
- <button className={`field-${id}-action-button`} onClick={iconAction}>
231
- <Icon name={icon} size="18px" />
232
- </button>
233
- )}
234
- </FormFieldWrapper>
235
- );
236
- }
237
- }
238
-
239
- export default compose(
240
- injectIntl,
241
- connect(
242
- (state, props) => ({
243
- indexes: keys(state.querystring.indexes),
244
- }),
245
- {
246
- getQuerystring,
88
+ setError(error);
89
+ };
90
+
91
+ useEffect(
92
+ () => {
93
+ if (focus) ref.current.focus();
94
+
95
+ dispatch(getQuerystring());
96
+ fieldValidation(value);
247
97
  },
248
- ),
249
- )(IdWidget);
98
+ // eslint-disable-next-line react-hooks/exhaustive-deps
99
+ [focus, value, dispatch],
100
+ );
101
+
102
+ const handleChange = ({ target }) => {
103
+ fieldValidation(target.value);
104
+ onChange(id, target.value === '' ? undefined : target.value);
105
+ };
106
+
107
+ const handleBlur = ({ target }) => {
108
+ fieldValidation(target.value);
109
+ onBlur(id, target.value === '' ? undefined : target.value);
110
+ };
111
+
112
+ props = {
113
+ ...props,
114
+ error: concat(props.error, errors),
115
+ };
116
+
117
+ return (
118
+ <FormFieldWrapper {...props} className="text">
119
+ <Input
120
+ id={`field-${id}`}
121
+ name={id}
122
+ value={value || ''}
123
+ disabled={isDisabled}
124
+ icon={icon || null}
125
+ placeholder={placeholder}
126
+ onChange={handleChange}
127
+ onBlur={handleBlur}
128
+ onClick={() => onClick()}
129
+ ref={ref}
130
+ minLength={minLength || null}
131
+ maxLength={maxLength || null}
132
+ />
133
+ {icon && iconAction && (
134
+ <button className={`field-${id}-action-button`} onClick={iconAction}>
135
+ <Icon name={icon} size="18px" />
136
+ </button>
137
+ )}
138
+ </FormFieldWrapper>
139
+ );
140
+ };
141
+
142
+ export default IdWidget;
143
+
144
+ IdWidget.propTypes = {
145
+ id: PropTypes.string.isRequired,
146
+ title: PropTypes.string.isRequired,
147
+ description: PropTypes.string,
148
+ required: PropTypes.bool,
149
+ error: PropTypes.arrayOf(PropTypes.string),
150
+ value: PropTypes.string,
151
+ focus: PropTypes.bool,
152
+ onChange: PropTypes.func,
153
+ onBlur: PropTypes.func,
154
+ onClick: PropTypes.func,
155
+ onEdit: PropTypes.func,
156
+ onDelete: PropTypes.func,
157
+ icon: PropTypes.shape({
158
+ xmlns: PropTypes.string,
159
+ viewBox: PropTypes.string,
160
+ content: PropTypes.string,
161
+ }),
162
+ iconAction: PropTypes.func,
163
+ minLength: PropTypes.number,
164
+ maxLength: PropTypes.number,
165
+ wrapped: PropTypes.bool,
166
+ placeholder: PropTypes.string,
167
+ };
168
+
169
+ IdWidget.defaultProps = {
170
+ description: null,
171
+ required: false,
172
+ error: [],
173
+ value: null,
174
+ onChange: () => {},
175
+ onBlur: () => {},
176
+ onClick: () => {},
177
+ onEdit: null,
178
+ onDelete: null,
179
+ focus: false,
180
+ icon: null,
181
+ iconAction: null,
182
+ minLength: null,
183
+ maxLength: null,
184
+ };
@@ -1,136 +1,104 @@
1
- /**
2
- * TextWidget component.
3
- * @module components/manage/Widgets/TextWidget
4
- */
5
-
6
- import React, { Component } from 'react';
1
+ import { useEffect, useRef } from 'react';
7
2
  import PropTypes from 'prop-types';
8
3
  import { Input } from 'semantic-ui-react';
9
4
 
10
- import { injectIntl } from 'react-intl';
11
5
  import { Icon } from '@plone/volto/components';
12
6
  import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
13
7
 
14
- /**
15
- * The simple text widget.
16
- *
17
- * It is the default fallback widget, so if no other widget is found based on
18
- * passed field properties, it will be used.
19
- */
20
- class TextWidget extends Component {
21
- /**
22
- * Property types.
23
- * @property {Object} propTypes Property types.
24
- * @static
25
- */
26
- static propTypes = {
27
- id: PropTypes.string.isRequired,
28
- title: PropTypes.string.isRequired,
29
- description: PropTypes.string,
30
- required: PropTypes.bool,
31
- error: PropTypes.arrayOf(PropTypes.string),
32
- value: PropTypes.string,
33
- focus: PropTypes.bool,
34
- onChange: PropTypes.func,
35
- onBlur: PropTypes.func,
36
- onClick: PropTypes.func,
37
- onEdit: PropTypes.func,
38
- onDelete: PropTypes.func,
39
- icon: PropTypes.shape({
40
- xmlns: PropTypes.string,
41
- viewBox: PropTypes.string,
42
- content: PropTypes.string,
43
- }),
44
- iconAction: PropTypes.func,
45
- minLength: PropTypes.number,
46
- maxLength: PropTypes.number,
47
- wrapped: PropTypes.bool,
48
- placeholder: PropTypes.string,
49
- };
8
+ const TextWidget = (props) => {
9
+ const {
10
+ id,
11
+ value,
12
+ onChange,
13
+ onBlur,
14
+ onClick,
15
+ icon,
16
+ iconAction,
17
+ minLength,
18
+ maxLength,
19
+ placeholder,
20
+ isDisabled,
21
+ focus,
22
+ } = props;
50
23
 
51
- /**
52
- * Default properties.
53
- * @property {Object} defaultProps Default properties.
54
- * @static
55
- */
56
- static defaultProps = {
57
- description: null,
58
- required: false,
59
- error: [],
60
- value: null,
61
- onChange: () => {},
62
- onBlur: () => {},
63
- onClick: () => {},
64
- onEdit: null,
65
- onDelete: null,
66
- focus: false,
67
- icon: null,
68
- iconAction: null,
69
- minLength: null,
70
- maxLength: null,
71
- };
24
+ const ref = useRef();
72
25
 
73
- /**
74
- * Component did mount lifecycle method
75
- * @method componentDidMount
76
- * @returns {undefined}
77
- */
78
- componentDidMount() {
79
- if (this.props.focus) {
80
- this.node.focus();
26
+ useEffect(() => {
27
+ if (focus) {
28
+ ref.current.focus();
81
29
  }
82
- }
30
+ // eslint-disable-next-line react-hooks/exhaustive-deps
31
+ }, []);
32
+
33
+ return (
34
+ <FormFieldWrapper {...props} className="text">
35
+ <Input
36
+ id={`field-${id}`}
37
+ name={id}
38
+ value={value || ''}
39
+ disabled={isDisabled}
40
+ icon={icon || null}
41
+ placeholder={placeholder}
42
+ onChange={({ target }) =>
43
+ onChange(id, target.value === '' ? undefined : target.value)
44
+ }
45
+ ref={ref}
46
+ onBlur={({ target }) =>
47
+ onBlur(id, target.value === '' ? undefined : target.value)
48
+ }
49
+ onClick={() => onClick()}
50
+ minLength={minLength || null}
51
+ maxLength={maxLength || null}
52
+ />
53
+ {icon && iconAction && (
54
+ <button className={`field-${id}-action-button`} onClick={iconAction}>
55
+ <Icon name={icon} size="18px" />
56
+ </button>
57
+ )}
58
+ </FormFieldWrapper>
59
+ );
60
+ };
83
61
 
84
- /**
85
- * Render method.
86
- * @method render
87
- * @returns {string} Markup for the component.
88
- */
89
- render() {
90
- const {
91
- id,
92
- value,
93
- onChange,
94
- onBlur,
95
- onClick,
96
- icon,
97
- iconAction,
98
- minLength,
99
- maxLength,
100
- placeholder,
101
- isDisabled,
102
- } = this.props;
62
+ export default TextWidget;
103
63
 
104
- return (
105
- <FormFieldWrapper {...this.props} className="text">
106
- <Input
107
- id={`field-${id}`}
108
- name={id}
109
- value={value || ''}
110
- disabled={isDisabled}
111
- icon={icon || null}
112
- placeholder={placeholder}
113
- onChange={({ target }) =>
114
- onChange(id, target.value === '' ? undefined : target.value)
115
- }
116
- ref={(node) => {
117
- this.node = node;
118
- }}
119
- onBlur={({ target }) =>
120
- onBlur(id, target.value === '' ? undefined : target.value)
121
- }
122
- onClick={() => onClick()}
123
- minLength={minLength || null}
124
- maxLength={maxLength || null}
125
- />
126
- {icon && iconAction && (
127
- <button className={`field-${id}-action-button`} onClick={iconAction}>
128
- <Icon name={icon} size="18px" />
129
- </button>
130
- )}
131
- </FormFieldWrapper>
132
- );
133
- }
134
- }
64
+ TextWidget.propTypes = {
65
+ id: PropTypes.string.isRequired,
66
+ title: PropTypes.string.isRequired,
67
+ description: PropTypes.string,
68
+ required: PropTypes.bool,
69
+ error: PropTypes.arrayOf(PropTypes.string),
70
+ value: PropTypes.string,
71
+ focus: PropTypes.bool,
72
+ onChange: PropTypes.func,
73
+ onBlur: PropTypes.func,
74
+ onClick: PropTypes.func,
75
+ onEdit: PropTypes.func,
76
+ onDelete: PropTypes.func,
77
+ icon: PropTypes.shape({
78
+ xmlns: PropTypes.string,
79
+ viewBox: PropTypes.string,
80
+ content: PropTypes.string,
81
+ }),
82
+ iconAction: PropTypes.func,
83
+ minLength: PropTypes.number,
84
+ maxLength: PropTypes.number,
85
+ wrapped: PropTypes.bool,
86
+ placeholder: PropTypes.string,
87
+ };
135
88
 
136
- export default injectIntl(TextWidget);
89
+ TextWidget.defaultProps = {
90
+ description: null,
91
+ required: false,
92
+ error: [],
93
+ value: null,
94
+ onChange: () => {},
95
+ onBlur: () => {},
96
+ onClick: () => {},
97
+ onEdit: null,
98
+ onDelete: null,
99
+ focus: false,
100
+ icon: null,
101
+ iconAction: null,
102
+ minLength: null,
103
+ maxLength: null,
104
+ };
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import TextWidget from './TextWidget';
3
2
  import WidgetStory from './story';
4
3
 
@@ -6,7 +5,10 @@ export const Text = WidgetStory.bind({
6
5
  props: { id: 'text', title: 'Text' },
7
6
  widget: TextWidget,
8
7
  });
9
-
8
+ Text.args = {
9
+ description: 'description',
10
+ placeholder: 'placeholder',
11
+ };
10
12
  export default {
11
13
  title: 'Edit Widgets/Text',
12
14
  component: TextWidget,
@@ -17,5 +19,14 @@ export default {
17
19
  </div>
18
20
  ),
19
21
  ],
20
- argTypes: {},
22
+ argTypes: {
23
+ description: {
24
+ control: 'text',
25
+ description: 'description',
26
+ },
27
+ placeholder: {
28
+ control: 'text',
29
+ description: 'placeholder',
30
+ },
31
+ },
21
32
  };
@@ -151,6 +151,11 @@ export class App extends Component {
151
151
  [trim(join(split(this.props.pathname, '/'), ' section-'))]:
152
152
  this.props.pathname !== '/',
153
153
  siteroot: this.props.pathname === '/',
154
+ [`is-adding-contenttype-${decodeURIComponent(
155
+ this.props.location?.search?.replace('?type=', ''),
156
+ )
157
+ .replace(' ', '')
158
+ .toLowerCase()}`]: this.props.location?.search,
154
159
  'is-authenticated': !!this.props.token,
155
160
  'is-anonymous': !this.props.token,
156
161
  'cms-ui': isCmsUI,
@@ -42,6 +42,7 @@ const Footer = ({ intl }) => {
42
42
  textAlign="center"
43
43
  id="footer"
44
44
  aria-label="Footer"
45
+ tabIndex="-1"
45
46
  >
46
47
  <Container>
47
48
  <Segment basic inverted color="grey" className="discreet">
@@ -49,7 +49,7 @@ const Navigation = (props) => {
49
49
  setisMobileMenuOpen(false);
50
50
  };
51
51
  return (
52
- <nav className="navigation" id="navigation" aria-label="Site">
52
+ <nav className="navigation" id="navigation" aria-label="Site" tabIndex="-1">
53
53
  {items?.length ? (
54
54
  <div className="hamburger-wrapper mobile tablet only">
55
55
  <button
@@ -1,6 +1,5 @@
1
1
  import { useLocation } from 'react-router-dom';
2
2
  import config from '@plone/volto/registry';
3
-
4
3
  import type { Content } from '@plone/types';
5
4
 
6
5
  /*
@@ -17,11 +16,11 @@ const SlotRenderer = ({
17
16
  content: Content;
18
17
  navRoot?: Content;
19
18
  }) => {
20
- const pathname = useLocation().pathname;
19
+ const location = useLocation();
21
20
 
22
21
  let slots = config.getSlot(name, {
23
22
  content,
24
- pathname,
23
+ location: location as any, // Since we are using an older version of history, we need to cast it to any
25
24
  // This is to cover the use case while adding a new content and we don't have
26
25
  // have the navRoot information in the initial content. This will be
27
26
  // useful for SlotRenderers rendered in the `Add` route.
@@ -48,7 +47,7 @@ const SlotRenderer = ({
48
47
  <SlotComponent
49
48
  key={name}
50
49
  content={content}
51
- pathname={pathname}
50
+ location={location}
52
51
  navRoot={navRoot}
53
52
  />
54
53
  );