@plone/volto 16.8.0 → 16.9.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 (49) hide show
  1. package/.changelog.draft +12 -6
  2. package/.yarn/install-state.gz +0 -0
  3. package/CHANGELOG.md +30 -0
  4. package/cypress/support/commands.js +6 -0
  5. package/news/4104.internal +1 -0
  6. package/news/4165.feature +1 -0
  7. package/news/4189.bugfix +1 -0
  8. package/news/4194.bugfix +1 -0
  9. package/news/4223.bugfix +1 -0
  10. package/news/4231.feature +1 -0
  11. package/news/4282.feature +1 -0
  12. package/news/4285.feature +1 -0
  13. package/news/4311.bugfix +1 -0
  14. package/news/4313.feature +1 -0
  15. package/package.json +3 -2
  16. package/packages/volto-slate/package.json +1 -1
  17. package/packages/volto-slate/src/blocks/Text/DetachedTextBlockEditor.jsx +1 -0
  18. package/packages/volto-slate/src/editor/SlateEditor.jsx +5 -1
  19. package/packages/volto-slate/src/editor/ui/InlineToolbar.jsx +3 -1
  20. package/packages/volto-slate/src/editor/ui/SlateToolbar.jsx +3 -1
  21. package/src/components/manage/Blocks/Block/Edit.jsx +1 -0
  22. package/src/components/manage/Blocks/Listing/ListingData.jsx +5 -2
  23. package/src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx +1 -1
  24. package/src/components/manage/Edit/Edit.jsx +5 -2
  25. package/src/components/manage/Toolbar/Toolbar.jsx +22 -5
  26. package/src/components/manage/UniversalLink/UniversalLink.jsx +2 -2
  27. package/src/components/manage/Widgets/ArrayWidget.jsx +1 -0
  28. package/src/components/manage/Widgets/SelectWidget.jsx +1 -0
  29. package/src/components/manage/Widgets/TokenWidget.jsx +1 -0
  30. package/src/components/theme/App/App.jsx +39 -13
  31. package/src/components/theme/View/View.jsx +9 -2
  32. package/src/config/index.js +10 -2
  33. package/src/helpers/Blocks/Blocks.js +7 -2
  34. package/src/helpers/Blocks/Blocks.test.js +44 -5
  35. package/src/helpers/FormValidation/FormValidation.js +11 -9
  36. package/src/helpers/ScrollToTop/ScrollToTop.jsx +4 -1
  37. package/src/helpers/Utils/Utils.js +5 -3
  38. package/src/middleware/api.js +22 -15
  39. package/src/reducers/actions/actions.js +36 -8
  40. package/src/reducers/actions/actions.test.js +87 -1
  41. package/src/reducers/breadcrumbs/breadcrumbs.js +50 -13
  42. package/src/reducers/breadcrumbs/breadcrumbs.test.js +47 -1
  43. package/src/reducers/navigation/navigation.js +41 -9
  44. package/src/reducers/navigation/navigation.test.js +49 -1
  45. package/src/reducers/types/types.js +36 -8
  46. package/src/reducers/types/types.test.js +31 -1
  47. package/src/registry.js +18 -0
  48. package/src/registry.test.js +34 -0
  49. package/test-setup-config.js +3 -0
package/.changelog.draft CHANGED
@@ -1,15 +1,21 @@
1
- ## 16.8.0 (2023-01-18)
1
+ ## 16.9.0 (2023-01-27)
2
2
 
3
3
  ### Feature
4
4
 
5
- - Autocomplete widget support for QueryStringWidget @sneridagh [#4177](https://github.com/plone/volto/issues/4177)
6
- - Enhance the StyleWrapper classNames generator by adding look around classNames depending on the sorounding previous/next blocks. @sneridagh [#4260](https://github.com/plone/volto/issues/4260)
5
+ - Enable scrolling to ids via hashes in internal links @jackahl [#4165](https://github.com/plone/volto/issues/4165)
6
+ - Read listing block schema from configuration registry @pnicolli [#4231](https://github.com/plone/volto/issues/4231)
7
+ - Add displayName when registering a component @sneridagh [#4282](https://github.com/plone/volto/issues/4282)
8
+ - Support for all default expanders (breadcrumbs, navigation, actions, types) in actions/reducers. Conditional loading of actions if the expanders are present. @sneridagh [#4285](https://github.com/plone/volto/issues/4285)
9
+ - Add `addNewBlock` Cypress support command @sneridagh [#4313](https://github.com/plone/volto/issues/4313)
7
10
 
8
11
  ### Bugfix
9
12
 
10
- - Fix typo in 4260 @sneridagh [#4268](https://github.com/plone/volto/issues/4268)
13
+ - Fixed maxLength validation for string type fields @pnicolli [#4189](https://github.com/plone/volto/issues/4189)
14
+ - bugfix : add pathname as required proptype in Blocks/Edit @akshatgarg12 [#4194](https://github.com/plone/volto/issues/4194)
15
+ - (Fix) Select Widgets scrolls the page when the options are not visible @dobri1408 [#4223](https://github.com/plone/volto/issues/4223)
16
+ - Updated volto-slate to check for slateSettings before falling back to config @danalvrz [#4311](https://github.com/plone/volto/issues/4311)
11
17
 
12
- ### Documentation
18
+ ### Internal
13
19
 
14
- - Update links to docs to use correct versions. [stevepiercy] [#4256](https://github.com/plone/volto/issues/4256)
20
+ - Updated 4 Dependencies @SaiRev0 [#4104](https://github.com/plone/volto/issues/4104)
15
21
 
Binary file
package/CHANGELOG.md CHANGED
@@ -8,6 +8,36 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 16.9.0 (2023-01-27)
12
+
13
+ ### Feature
14
+
15
+ - Enable scrolling to ids via hashes in internal links @jackahl [#4165](https://github.com/plone/volto/issues/4165)
16
+ - Read listing block schema from configuration registry @pnicolli [#4231](https://github.com/plone/volto/issues/4231)
17
+ - Add displayName when registering a component @sneridagh [#4282](https://github.com/plone/volto/issues/4282)
18
+ - Support for all default expanders (breadcrumbs, navigation, actions, types) in actions/reducers. Conditional loading of actions if the expanders are present. @sneridagh [#4285](https://github.com/plone/volto/issues/4285)
19
+ - Add `addNewBlock` Cypress support command @sneridagh [#4313](https://github.com/plone/volto/issues/4313)
20
+
21
+ ### Bugfix
22
+
23
+ - Fixed maxLength validation for string type fields @pnicolli [#4189](https://github.com/plone/volto/issues/4189)
24
+ - bugfix : add pathname as required proptype in Blocks/Edit @akshatgarg12 [#4194](https://github.com/plone/volto/issues/4194)
25
+ - (Fix) Select Widgets scrolls the page when the options are not visible @dobri1408 [#4223](https://github.com/plone/volto/issues/4223)
26
+ - Updated volto-slate to check for slateSettings before falling back to config @danalvrz [#4311](https://github.com/plone/volto/issues/4311)
27
+
28
+ ### Internal
29
+
30
+ - Updated 4 Dependencies @SaiRev0 [#4104](https://github.com/plone/volto/issues/4104)
31
+
32
+
33
+ ## 16.8.1 (2023-01-18)
34
+
35
+ ### Bugfix
36
+
37
+ - Fix StyleWrapper extenders, the classNames were not being re-fed into the pipe @sneridagh [#4275](https://github.com/plone/volto/issues/4275)
38
+ - Fix bug where label of search facet wasn't translated when the content object is being translated @robgietema
39
+
40
+
11
41
  ## 16.8.0 (2023-01-18)
12
42
 
13
43
  ### Feature
@@ -806,6 +806,12 @@ function createHtmlPasteEvent(htmlContent) {
806
806
  );
807
807
  }
808
808
 
809
+ Cypress.Commands.add('addNewBlock', (blockName, createNewSlate = false) => {
810
+ let block;
811
+ block = cy.getSlate(createNewSlate).type(`/${blockName}{enter}`);
812
+ return block;
813
+ });
814
+
809
815
  Cypress.Commands.add('navigate', (route = '') => {
810
816
  return cy.window().its('appHistory').invoke('push', route);
811
817
  });
@@ -0,0 +1 @@
1
+ Updated 4 Dependencies @SaiRev0
@@ -0,0 +1 @@
1
+ Enable scrolling to ids via hashes in internal links @jackahl
@@ -0,0 +1 @@
1
+ Fixed maxLength validation for string type fields @pnicolli
@@ -0,0 +1 @@
1
+ bugfix : add pathname as required proptype in Blocks/Edit @akshatgarg12
@@ -0,0 +1 @@
1
+ (Fix) Select Widgets scrolls the page when the options are not visible @dobri1408
@@ -0,0 +1 @@
1
+ Read listing block schema from configuration registry @pnicolli
@@ -0,0 +1 @@
1
+ Add displayName when registering a component @sneridagh
@@ -0,0 +1 @@
1
+ Support for all default expanders (breadcrumbs, navigation, actions, types) in actions/reducers. Conditional loading of actions if the expanders are present. @sneridagh
@@ -0,0 +1 @@
1
+ Updated volto-slate to check for slateSettings before falling back to config @danalvrz
@@ -0,0 +1 @@
1
+ Add `addNewBlock` Cypress support command @sneridagh
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.8.0",
12
+ "version": "16.9.0",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -281,7 +281,7 @@
281
281
  "eslint-plugin-prettier": "3.1.3",
282
282
  "eslint-plugin-react": "7.20.0",
283
283
  "eslint-plugin-react-hooks": "4.0.2",
284
- "express": "4.17.1",
284
+ "express": "4.17.3",
285
285
  "filesize": "6",
286
286
  "glob": "7.1.6",
287
287
  "hamburgers": "1.1.3",
@@ -349,6 +349,7 @@
349
349
  "react-router": "5.2.0",
350
350
  "react-router-config": "5.1.1",
351
351
  "react-router-dom": "5.2.0",
352
+ "react-router-hash-link": "2.4.3",
352
353
  "react-select": "4.3.1",
353
354
  "react-select-async-paginate": "0.5.3",
354
355
  "react-share": "2.3.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.8.0",
3
+ "version": "16.9.0",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -51,6 +51,7 @@ export const DetachedTextBlockEditor = (props) => {
51
51
  value={value}
52
52
  block={block /* is this needed? */}
53
53
  debug={DEBUG}
54
+ slateSettings={props.slateSettings}
54
55
  onFocus={() => {
55
56
  if (!selected) {
56
57
  onSelectBlock(block);
@@ -262,7 +262,11 @@ class SlateEditor extends Component {
262
262
  >
263
263
  {selected ? (
264
264
  <>
265
- <InlineToolbar editor={editor} className={className} />
265
+ <InlineToolbar
266
+ editor={editor}
267
+ className={className}
268
+ slateSettings={this.props.slateSettings}
269
+ />
266
270
  {Object.keys(slateSettings.elementToolbarButtons).map(
267
271
  (t, i) => {
268
272
  return (
@@ -17,7 +17,8 @@ const InlineToolbar = (props) => {
17
17
  setShowExpandedToolbar,
18
18
  } = props;
19
19
 
20
- const { slate } = config.settings;
20
+ const slate = props.slateSettings || config.settings.slate;
21
+
21
22
  const [showMainToolbar, setShowMainToolbar] = React.useState(
22
23
  !!(editor.selection && hasRangeSelection(editor)),
23
24
  );
@@ -58,6 +59,7 @@ const InlineToolbar = (props) => {
58
59
  showExpandedToolbar={showExpandedToolbar}
59
60
  setShowExpandedToolbar={setShowExpandedToolbar}
60
61
  show={showMainToolbar}
62
+ slateSettings={slate}
61
63
  />
62
64
  <SlateContextToolbar
63
65
  editor={editor}
@@ -26,7 +26,9 @@ const SlateToolbar = (props) => {
26
26
  enableExpando = false,
27
27
  show,
28
28
  } = props;
29
- const { slate } = config.settings;
29
+
30
+ const slate = props.slateSettings || config.settings.slate;
31
+
30
32
  const { toolbarButtons, expandedToolbarButtons, buttons } = slate;
31
33
 
32
34
  function renderButton(name, index) {
@@ -52,6 +52,7 @@ export class Edit extends Component {
52
52
  onMoveBlock: PropTypes.func.isRequired,
53
53
  onDeleteBlock: PropTypes.func.isRequired,
54
54
  editable: PropTypes.bool,
55
+ pathname: PropTypes.string.isRequired,
55
56
  };
56
57
 
57
58
  /**
@@ -2,12 +2,15 @@ import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { useIntl } from 'react-intl';
4
4
  import { BlockDataForm } from '@plone/volto/components';
5
- import { schemaListing } from './schema';
5
+ import config from '@plone/volto/registry';
6
6
 
7
7
  const ListingData = (props) => {
8
8
  const { data, block, onChangeBlock } = props;
9
9
  const intl = useIntl();
10
- const schema = schemaListing({ ...props, intl });
10
+ const schema = config.blocks.blocksConfig.listing.blockSchema({
11
+ ...props,
12
+ intl,
13
+ });
11
14
 
12
15
  return (
13
16
  <BlockDataForm
@@ -195,7 +195,7 @@ class SelectWidget extends Component {
195
195
  styles={customSelectStyles}
196
196
  theme={selectTheme}
197
197
  components={{ DropdownIndicator, Option }}
198
- value={value}
198
+ value={{ value: value?.value, label: indexes[value?.value]?.title }}
199
199
  onChange={(data) => {
200
200
  let dataValue = [];
201
201
  if (Array.isArray(data)) {
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
8
8
  import { Helmet } from '@plone/volto/helpers';
9
9
  import { connect } from 'react-redux';
10
10
  import { compose } from 'redux';
11
- import { asyncConnect } from '@plone/volto/helpers';
11
+ import { asyncConnect, hasApiExpander } from '@plone/volto/helpers';
12
12
  import { defineMessages, injectIntl } from 'react-intl';
13
13
  import { Button, Grid, Menu } from 'semantic-ui-react';
14
14
  import { Portal } from 'react-portal';
@@ -475,7 +475,10 @@ export default compose(
475
475
  {
476
476
  key: 'actions',
477
477
  promise: async ({ location, store: { dispatch } }) => {
478
- await dispatch(listActions(getBaseUrl(location.pathname)));
478
+ // Do not trigger the actions action if the expander is present
479
+ if (!hasApiExpander('actions', getBaseUrl(location.pathname))) {
480
+ return await dispatch(listActions(getBaseUrl(location.pathname)));
481
+ }
479
482
  },
480
483
  },
481
484
  {
@@ -29,7 +29,12 @@ import {
29
29
  unlockContent,
30
30
  } from '@plone/volto/actions';
31
31
  import { Icon } from '@plone/volto/components';
32
- import { BodyClass, getBaseUrl, getCookieOptions } from '@plone/volto/helpers';
32
+ import {
33
+ BodyClass,
34
+ getBaseUrl,
35
+ getCookieOptions,
36
+ hasApiExpander,
37
+ } from '@plone/volto/helpers';
33
38
  import { Pluggable } from '@plone/volto/components/manage/Pluggable';
34
39
 
35
40
  import penSVG from '@plone/volto/icons/pen.svg';
@@ -197,8 +202,14 @@ class Toolbar extends Component {
197
202
  * @returns {undefined}
198
203
  */
199
204
  componentDidMount() {
200
- this.props.listActions(getBaseUrl(this.props.pathname));
201
- this.props.getTypes(getBaseUrl(this.props.pathname));
205
+ // Do not trigger the actions action if the expander is present
206
+ if (!hasApiExpander('actions', getBaseUrl(this.props.pathname))) {
207
+ this.props.listActions(getBaseUrl(this.props.pathname));
208
+ }
209
+ // Do not trigger the types action if the expander is present
210
+ if (!hasApiExpander('types', getBaseUrl(this.props.pathname))) {
211
+ this.props.getTypes(getBaseUrl(this.props.pathname));
212
+ }
202
213
  this.props.setExpandedToolbar(this.state.expanded);
203
214
  document.addEventListener('mousedown', this.handleClickOutside, false);
204
215
  }
@@ -211,8 +222,14 @@ class Toolbar extends Component {
211
222
  */
212
223
  UNSAFE_componentWillReceiveProps(nextProps) {
213
224
  if (nextProps.pathname !== this.props.pathname) {
214
- this.props.listActions(getBaseUrl(nextProps.pathname));
215
- this.props.getTypes(getBaseUrl(nextProps.pathname));
225
+ // Do not trigger the actions action if the expander is present
226
+ if (!hasApiExpander('actions', getBaseUrl(nextProps.pathname))) {
227
+ this.props.listActions(getBaseUrl(nextProps.pathname));
228
+ }
229
+ // Do not trigger the types action if the expander is present
230
+ if (!hasApiExpander('types', getBaseUrl(nextProps.pathname))) {
231
+ this.props.getTypes(getBaseUrl(nextProps.pathname));
232
+ }
216
233
  }
217
234
 
218
235
  // Unlock
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { Link } from 'react-router-dom';
8
+ import { HashLink as Link } from 'react-router-hash-link';
9
9
  import { useSelector } from 'react-redux';
10
10
  import {
11
11
  flattenToAppURL,
@@ -78,13 +78,13 @@ const UniversalLink = ({
78
78
  const checkedURL = URLUtils.checkAndNormalizeUrl(url);
79
79
 
80
80
  url = checkedURL.url;
81
-
82
81
  let tag = (
83
82
  <Link
84
83
  to={flattenToAppURL(url)}
85
84
  target={openLinkInNewTab ?? false ? '_blank' : null}
86
85
  title={title}
87
86
  className={className}
87
+ smooth={config.settings.hashLinkSmoothScroll}
88
88
  {...props}
89
89
  >
90
90
  {children}
@@ -307,6 +307,7 @@ class ArrayWidget extends Component {
307
307
  // react-sortable-hoc props:
308
308
  axis="xy"
309
309
  onSortEnd={this.onSortEnd}
310
+ menuShouldScrollIntoView={false}
310
311
  distance={4}
311
312
  // small fix for https://github.com/clauderic/react-sortable-hoc/pull/352:
312
313
  getHelperDimensions={({ node }) => node.getBoundingClientRect()}
@@ -210,6 +210,7 @@ class SelectWidget extends Component {
210
210
  id={`field-${id}`}
211
211
  key={choices}
212
212
  name={id}
213
+ menuShouldScrollIntoView={false}
213
214
  isDisabled={disabled}
214
215
  isSearchable={true}
215
216
  className="react-select-container"
@@ -174,6 +174,7 @@ class TokenWidget extends Component {
174
174
  <CreatableSelect
175
175
  id={`field-${this.props.id}`}
176
176
  key={this.props.id}
177
+ menuShouldScrollIntoView={false}
177
178
  isDisabled={this.props.isDisabled}
178
179
  className="react-select-container"
179
180
  classNamePrefix="react-select"
@@ -32,7 +32,13 @@ import {
32
32
  AppExtras,
33
33
  SkipLinks,
34
34
  } from '@plone/volto/components';
35
- import { BodyClass, getBaseUrl, getView, isCmsUi } from '@plone/volto/helpers';
35
+ import {
36
+ BodyClass,
37
+ getBaseUrl,
38
+ getView,
39
+ hasApiExpander,
40
+ isCmsUi,
41
+ } from '@plone/volto/helpers';
36
42
  import {
37
43
  getBreadcrumbs,
38
44
  getContent,
@@ -257,8 +263,15 @@ export default compose(
257
263
  asyncConnect([
258
264
  {
259
265
  key: 'breadcrumbs',
260
- promise: ({ location, store: { dispatch } }) =>
261
- __SERVER__ && dispatch(getBreadcrumbs(getBaseUrl(location.pathname))),
266
+ promise: ({ location, store: { dispatch } }) => {
267
+ // Do not trigger the breadcrumbs action if the expander is present
268
+ if (
269
+ __SERVER__ &&
270
+ !hasApiExpander('breadcrumbs', getBaseUrl(location.pathname))
271
+ ) {
272
+ return dispatch(getBreadcrumbs(getBaseUrl(location.pathname)));
273
+ }
274
+ },
262
275
  },
263
276
  {
264
277
  key: 'content',
@@ -267,19 +280,32 @@ export default compose(
267
280
  },
268
281
  {
269
282
  key: 'navigation',
270
- promise: ({ location, store: { dispatch } }) =>
271
- __SERVER__ &&
272
- dispatch(
273
- getNavigation(
274
- getBaseUrl(location.pathname),
275
- config.settings.navDepth,
276
- ),
277
- ),
283
+ promise: ({ location, store: { dispatch } }) => {
284
+ // Do not trigger the navigation action if the expander is present
285
+ if (
286
+ __SERVER__ &&
287
+ !hasApiExpander('navigation', getBaseUrl(location.pathname))
288
+ ) {
289
+ return dispatch(
290
+ getNavigation(
291
+ getBaseUrl(location.pathname),
292
+ config.settings.navDepth,
293
+ ),
294
+ );
295
+ }
296
+ },
278
297
  },
279
298
  {
280
299
  key: 'types',
281
- promise: ({ location, store: { dispatch } }) =>
282
- __SERVER__ && dispatch(getTypes(getBaseUrl(location.pathname))),
300
+ promise: ({ location, store: { dispatch } }) => {
301
+ // Do not trigger the types action if the expander is present
302
+ if (
303
+ __SERVER__ &&
304
+ !hasApiExpander('types', getBaseUrl(location.pathname))
305
+ ) {
306
+ return dispatch(getTypes(getBaseUrl(location.pathname)));
307
+ }
308
+ },
283
309
  },
284
310
  {
285
311
  key: 'workflow',
@@ -24,6 +24,7 @@ import {
24
24
  getBaseUrl,
25
25
  flattenToAppURL,
26
26
  getLayoutFieldname,
27
+ hasApiExpander,
27
28
  } from '@plone/volto/helpers';
28
29
 
29
30
  import config from '@plone/volto/registry';
@@ -118,7 +119,10 @@ class View extends Component {
118
119
  };
119
120
 
120
121
  componentDidMount() {
121
- this.props.listActions(getBaseUrl(this.props.pathname));
122
+ // Do not trigger the actions action if the expander is present
123
+ if (!hasApiExpander('actions', getBaseUrl(this.props.pathname))) {
124
+ this.props.listActions(getBaseUrl(this.props.pathname));
125
+ }
122
126
  this.props.getContent(
123
127
  getBaseUrl(this.props.pathname),
124
128
  this.props.versionId,
@@ -134,7 +138,10 @@ class View extends Component {
134
138
  */
135
139
  UNSAFE_componentWillReceiveProps(nextProps) {
136
140
  if (nextProps.pathname !== this.props.pathname) {
137
- this.props.listActions(getBaseUrl(nextProps.pathname));
141
+ // Do not trigger the actions action if the expander is present
142
+ if (!hasApiExpander('actions', getBaseUrl(nextProps.pathname))) {
143
+ this.props.listActions(getBaseUrl(nextProps.pathname));
144
+ }
138
145
  this.props.getContent(
139
146
  getBaseUrl(nextProps.pathname),
140
147
  this.props.versionId,
@@ -75,11 +75,18 @@ let config = {
75
75
  // The URL Volto is going to be served (see sensible defaults above)
76
76
  publicURL,
77
77
  apiPath,
78
- apiExpanders: [],
78
+ apiExpanders: [
79
+ // Add the following expanders for only issuing a single request.
80
+ // https://6.docs.plone.org/volto/configuration/settings-reference.html#term-apiExpanders
81
+ // {
82
+ // match: '',
83
+ // GET_CONTENT: ['breadcrumbs', 'navigation', 'actions', 'types'],
84
+ // },
85
+ ],
79
86
  // Internal proxy to bypass CORS *while developing*. NOT intended for production use.
80
87
  // In production is recommended you use a Seamless mode deployment using a web server in
81
88
  // front of both the frontend and the backend so you can bypass CORS safely.
82
- // https://docs.voltocms.com/deploying/seamless-mode/
89
+ // https://6.docs.plone.org/volto/deploying/seamless-mode.html
83
90
  devProxyToApiPath:
84
91
  process.env.RAZZLE_DEV_PROXY_API_PATH ||
85
92
  process.env.RAZZLE_API_PATH ||
@@ -169,6 +176,7 @@ let config = {
169
176
  workflowMapping,
170
177
  errorHandlers: [], // callables for unhandled errors
171
178
  styleClassNameConverters,
179
+ hashLinkSmoothScroll: false,
172
180
  styleClassNameExtenders,
173
181
  },
174
182
  experimental: {
@@ -489,10 +489,15 @@ export const buildStyleClassNamesFromData = (obj = {}, prefix = '') => {
489
489
  * @param {Object} params An object with data, content and block (current block id)
490
490
  * @return {Array} Extender classNames resultant array
491
491
  */
492
- export const buildStyleClassNamesExtenders = ({ block, content, data }) => {
492
+ export const buildStyleClassNamesExtenders = ({
493
+ block,
494
+ content,
495
+ data,
496
+ classNames,
497
+ }) => {
493
498
  return config.settings.styleClassNameExtenders.reduce(
494
499
  (acc, extender) => extender({ block, content, data, classNames: acc }),
495
- [],
500
+ classNames,
496
501
  );
497
502
  };
498
503
 
@@ -1063,9 +1063,9 @@ describe('Blocks', () => {
1063
1063
  };
1064
1064
  const block = 2;
1065
1065
  const data = content['blocks'][2];
1066
-
1066
+ const classNames = [];
1067
1067
  expect(
1068
- buildStyleClassNamesExtenders({ block, content, data }),
1068
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1069
1069
  ).toStrictEqual([
1070
1070
  'next--is--slate',
1071
1071
  'previous--is--same--block-type',
@@ -1103,9 +1103,10 @@ describe('Blocks', () => {
1103
1103
  };
1104
1104
  const block = 2;
1105
1105
  const data = content['blocks'][2];
1106
+ const classNames = [];
1106
1107
 
1107
1108
  expect(
1108
- buildStyleClassNamesExtenders({ block, content, data }),
1109
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1109
1110
  ).toStrictEqual([
1110
1111
  'next--is--slate',
1111
1112
  'previous--is--same--block-type',
@@ -1140,9 +1141,10 @@ describe('Blocks', () => {
1140
1141
  };
1141
1142
  const block = 2;
1142
1143
  const data = content['blocks'][2];
1144
+ const classNames = [];
1143
1145
 
1144
1146
  expect(
1145
- buildStyleClassNamesExtenders({ block, content, data }),
1147
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1146
1148
  ).toStrictEqual([
1147
1149
  'next--is--slate',
1148
1150
  'next--is--same--block-type',
@@ -1174,10 +1176,47 @@ describe('Blocks', () => {
1174
1176
  };
1175
1177
  const block = 2;
1176
1178
  const data = content['blocks'][2];
1179
+ const classNames = [];
1180
+
1181
+ expect(
1182
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1183
+ ).toStrictEqual([
1184
+ 'next--is--slate',
1185
+ 'previous--is--same--block-type',
1186
+ 'is--last--of--block-type',
1187
+ 'previous--has--same--backgroundColor',
1188
+ 'next--has--different--backgroundColor',
1189
+ ]);
1190
+ });
1191
+
1192
+ it('grid + grid + slate grey - with existing classNames list', () => {
1193
+ const content = {
1194
+ blocks: {
1195
+ 1: {
1196
+ '@type': '__grid',
1197
+ },
1198
+ 2: {
1199
+ '@type': '__grid',
1200
+ },
1201
+ 3: {
1202
+ '@type': 'slate',
1203
+ styles: {
1204
+ backgroundColor: 'grey',
1205
+ },
1206
+ },
1207
+ },
1208
+ blocks_layout: {
1209
+ items: [1, 2, 3],
1210
+ },
1211
+ };
1212
+ const block = 2;
1213
+ const data = content['blocks'][2];
1214
+ const classNames = ['has--align--center'];
1177
1215
 
1178
1216
  expect(
1179
- buildStyleClassNamesExtenders({ block, content, data }),
1217
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1180
1218
  ).toStrictEqual([
1219
+ 'has--align--center',
1181
1220
  'next--is--slate',
1182
1221
  'previous--is--same--block-type',
1183
1222
  'is--last--of--block-type',