@eeacms/volto-eea-website-theme 3.19.1 → 4.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 (112) hide show
  1. package/.eslintrc.js +7 -6
  2. package/CHANGELOG.md +19 -26
  3. package/DEVELOP.md +19 -17
  4. package/README.md +19 -7
  5. package/docker-compose.yml +1 -1
  6. package/jest-addon.config.js +8 -4
  7. package/package.json +1 -1
  8. package/src/actions/navigation.js +1 -1
  9. package/src/components/manage/Blocks/ContextNavigation/ContextNavigationEdit.jsx +4 -2
  10. package/src/components/manage/Blocks/ContextNavigation/ContextNavigationEdit.test.jsx +25 -19
  11. package/src/components/manage/Blocks/ContextNavigation/ContextNavigationView.jsx +2 -1
  12. package/src/components/manage/Blocks/ContextNavigation/ContextNavigationView.test.jsx +6 -4
  13. package/src/components/manage/Blocks/ContextNavigation/variations/Accordion.jsx +2 -2
  14. package/src/components/manage/Blocks/ContextNavigation/variations/ReportNavigation.jsx +4 -2
  15. package/src/components/manage/Blocks/ContextNavigation/variations/ReportNavigation.test.jsx +1 -1
  16. package/src/components/manage/Blocks/GroupBlockTemplate/FlexGroup/FlexGroup.jsx +12 -44
  17. package/src/components/manage/Blocks/GroupBlockTemplate/FlexGroup/RenderBlocks.jsx +5 -4
  18. package/src/components/manage/Blocks/GroupBlockTemplate/FlexGroup/editor-flex.less +45 -4
  19. package/src/components/manage/Blocks/LayoutSettings/LayoutSettingsEdit.jsx +2 -1
  20. package/src/components/manage/Blocks/LayoutSettings/LayoutSettingsEdit.test.jsx +12 -4
  21. package/src/components/manage/Blocks/LayoutSettings/LayoutSettingsView.jsx +1 -1
  22. package/src/components/manage/Blocks/Title/Edit.jsx +3 -3
  23. package/src/components/manage/Blocks/Title/View.jsx +2 -1
  24. package/src/components/manage/Blocks/Title/variations/WebReport.jsx +2 -2
  25. package/src/components/manage/Blocks/Title/variations/WebReport.test.jsx +6 -4
  26. package/src/components/manage/Blocks/Title/variations/WebReportPage.jsx +2 -2
  27. package/src/components/manage/Blocks/Title/variations/WebReportPage.test.jsx +6 -4
  28. package/src/components/theme/Banner/View.jsx +1 -1
  29. package/src/components/theme/BaseTag.jsx +2 -1
  30. package/src/components/theme/BaseTag.test.jsx +7 -2
  31. package/src/components/theme/DraftBackground/DraftBackground.jsx +2 -1
  32. package/src/components/theme/Homepage/HomePageInverseView.jsx +3 -3
  33. package/src/components/theme/Homepage/HomePageInverseView.test.jsx +1 -1
  34. package/src/components/theme/Homepage/HomePageView.jsx +3 -3
  35. package/src/components/theme/Homepage/HomePageView.test.jsx +1 -1
  36. package/src/components/theme/Logo.jsx +3 -3
  37. package/src/components/theme/NotFound/GoneView.jsx +3 -2
  38. package/src/components/theme/NotFound/GoneView.test.jsx +5 -4
  39. package/src/components/theme/NotFound/NotFound.jsx +1 -1
  40. package/src/components/theme/NotFound/NotFound.test.jsx +3 -2
  41. package/src/components/theme/PrintLoader/PrintLoader.test.jsx +1 -1
  42. package/src/components/theme/SubsiteClass.jsx +6 -4
  43. package/src/components/theme/SubsiteClass.test.jsx +3 -2
  44. package/src/components/theme/WebReport/WebReportSectionView.jsx +2 -2
  45. package/src/components/theme/WebReport/WebReportSectionView.test.jsx +10 -5
  46. package/src/components/theme/Widgets/ADUserGroupSelectWidget.jsx +2 -2
  47. package/src/components/theme/Widgets/ContributorsViewWidget.jsx +1 -1
  48. package/src/components/theme/Widgets/CreatableSelectWidget.jsx +7 -4
  49. package/src/components/theme/Widgets/CreatorsViewWidget.jsx +1 -1
  50. package/src/components/theme/Widgets/DateWidget.jsx +1 -1
  51. package/src/components/theme/Widgets/DateWidget.test.js +1 -1
  52. package/src/components/theme/Widgets/DatetimeWidget.jsx +1 -1
  53. package/src/components/theme/Widgets/DatetimeWidget.test.js +1 -1
  54. package/src/components/theme/Widgets/ImageViewWidget.jsx +1 -0
  55. package/src/components/theme/Widgets/NavigationBehaviorWidget.jsx +7 -3
  56. package/src/components/theme/Widgets/NavigationBehaviorWidget.test.jsx +51 -46
  57. package/src/components/theme/Widgets/UserSelectWidget.jsx +13 -10
  58. package/src/customizations/@plone/volto-slate/blocks/Table/TableBlockView.jsx +3 -3
  59. package/src/customizations/@plone/volto-slate/blocks/Text/TextBlockView.jsx +2 -2
  60. package/src/customizations/@plone/volto-slate/editor/SlateEditor.jsx +23 -10
  61. package/src/customizations/@plone/volto-slate/editor/render.jsx +7 -3
  62. package/src/customizations/@plone/volto-slate/utils/blocks.js +11 -8
  63. package/src/customizations/volto/components/manage/Blocks/Grid/View.jsx +2 -2
  64. package/src/customizations/volto/components/manage/Blocks/Image/Edit.jsx +30 -27
  65. package/src/customizations/volto/components/manage/Blocks/Image/Edit.test.jsx +244 -246
  66. package/src/customizations/volto/components/manage/Blocks/Image/View.jsx +23 -25
  67. package/src/customizations/volto/components/manage/Blocks/LeadImage/Edit.jsx +6 -4
  68. package/src/customizations/volto/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +4 -2
  69. package/src/customizations/volto/components/manage/Blocks/LeadImage/View.jsx +2 -2
  70. package/src/customizations/volto/components/manage/Controlpanels/Groups/RenderGroups.jsx +1 -1
  71. package/src/customizations/volto/components/manage/Controlpanels/Groups/RenderGroups.test.jsx +108 -42
  72. package/src/customizations/volto/components/manage/Diff/DiffField.jsx +4 -3
  73. package/src/customizations/volto/components/manage/Display/Display.jsx +8 -7
  74. package/src/customizations/volto/components/manage/Sidebar/ObjectBrowserBody.jsx +42 -21
  75. package/src/customizations/volto/components/manage/Sidebar/ObjectBrowserNav.jsx +2 -1
  76. package/src/customizations/volto/components/manage/Sidebar/SidebarPopup.jsx +46 -24
  77. package/src/customizations/volto/components/manage/Sidebar/objectBrowserSelection.js +58 -0
  78. package/src/customizations/volto/components/manage/Toolbar/More.jsx +8 -10
  79. package/src/customizations/volto/components/manage/Widgets/NumberWidget.jsx +1 -1
  80. package/src/customizations/volto/components/manage/Widgets/NumberWidget.test.jsx +6 -1
  81. package/src/customizations/volto/components/manage/Widgets/ObjectBrowserWidget.jsx +66 -12
  82. package/src/customizations/volto/components/manage/Workflow/Workflow.jsx +10 -9
  83. package/src/customizations/volto/components/theme/Breadcrumbs/Breadcrumbs.jsx +3 -2
  84. package/src/customizations/volto/components/theme/Comments/Comments.jsx +9 -8
  85. package/src/customizations/volto/components/theme/Comments/Comments.test.jsx +29 -7
  86. package/src/customizations/volto/components/theme/ContactForm/ContactForm.jsx +1 -1
  87. package/src/customizations/volto/components/theme/ContactForm/ContactForm.test.js +5 -0
  88. package/src/customizations/volto/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +5 -7
  89. package/src/customizations/volto/components/theme/EventDetails/EventDetails.jsx +2 -2
  90. package/src/customizations/volto/components/theme/Footer/Footer.jsx +1 -1
  91. package/src/customizations/volto/components/theme/Header/Header.jsx +10 -8
  92. package/src/customizations/volto/components/theme/Header/Header.test.jsx +1 -1
  93. package/src/customizations/volto/components/theme/Header/LanguageSwitcher.jsx +3 -3
  94. package/src/customizations/volto/components/theme/Image/Image.jsx +4 -3
  95. package/src/customizations/volto/components/theme/Unauthorized/Unauthorized.jsx +1 -1
  96. package/src/customizations/volto/components/theme/View/DefaultView.jsx +4 -3
  97. package/src/customizations/volto/components/theme/View/EventView.jsx +3 -2
  98. package/src/customizations/volto/helpers/Html/Html.jsx +16 -6
  99. package/src/customizations/volto/helpers/Html/Readme.md +7 -1
  100. package/src/customizations/volto/reducers/breadcrumbs/breadcrumbs.js +3 -6
  101. package/src/customizations/volto/server.jsx +10 -10
  102. package/src/helpers/schema-utils.js +1 -1
  103. package/src/helpers/schema-utils.test.js +1 -1
  104. package/src/hocs/withErrorBoundary.jsx +1 -1
  105. package/src/hocs/withErrorBoundary.test.jsx +4 -11
  106. package/src/hocs/withRootNavigation.jsx +3 -2
  107. package/src/hocs/withRootNavigation.test.jsx +18 -14
  108. package/src/index.js +3 -3
  109. package/src/slate.js +1 -1
  110. package/src/customizations/volto/components/manage/Blocks/LeadImage/AlignChooser.jsx +0 -76
  111. package/src/customizations/volto/components/manage/Blocks/LeadImage/AlignChooser.test.js +0 -50
  112. package/src/customizations/volto/components/manage/Sidebar/SidebarPopup copy.jsx +0 -82
@@ -9,15 +9,18 @@ import React, { Component } from 'react';
9
9
  import PropTypes from 'prop-types';
10
10
  import { connect } from 'react-redux';
11
11
  import { compose } from 'redux';
12
- import { map } from 'lodash';
12
+ import map from 'lodash/map';
13
13
  import { defineMessages, injectIntl } from 'react-intl';
14
14
  import {
15
15
  getVocabFromHint,
16
16
  getVocabFromField,
17
17
  getVocabFromItems,
18
- } from '@plone/volto/helpers';
19
- import { FormFieldWrapper } from '@plone/volto/components';
20
- import { getVocabulary, getVocabularyTokenTitle } from '@plone/volto/actions';
18
+ } from '@plone/volto/helpers/Vocabularies/Vocabularies';
19
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
20
+ import {
21
+ getVocabulary,
22
+ getVocabularyTokenTitle,
23
+ } from '@plone/volto/actions/vocabularies/vocabularies';
21
24
  import { normalizeValue } from '@plone/volto/components/manage/Widgets/SelectUtils';
22
25
 
23
26
  import {
@@ -9,7 +9,7 @@ const CreatorsViewWidget = ({ value, content, children, className }) => {
9
9
  const key = `${label}-${index}`;
10
10
  return (
11
11
  <span key={key}>
12
- {index ? ', ' : ''}
12
+ {index > 0 && ', '}
13
13
  {children ? children(label) : label}
14
14
  </span>
15
15
  );
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
3
  import { useSelector } from 'react-redux';
4
- import { toBackendLang } from '@plone/volto/helpers';
4
+ import { toBackendLang } from '@plone/volto/helpers/Utils/Utils';
5
5
  import { formatDate } from '@plone/volto/helpers/Utils/Date';
6
6
  import config from '@plone/volto/registry';
7
7
 
@@ -22,7 +22,7 @@ describe('DateWidget', () => {
22
22
  </Provider>,
23
23
  );
24
24
  const json = component.toJSON();
25
- expect(json).toMatchSnapshot();
25
+ expect(json).toBeFalsy();
26
26
  });
27
27
 
28
28
  it('renders a date view widget component', () => {
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
3
  import { useSelector } from 'react-redux';
4
- import { toBackendLang } from '@plone/volto/helpers';
4
+ import { toBackendLang } from '@plone/volto/helpers/Utils/Utils';
5
5
  import { formatDate } from '@plone/volto/helpers/Utils/Date';
6
6
  import config from '@plone/volto/registry';
7
7
 
@@ -22,7 +22,7 @@ describe('DatetimeWidget', () => {
22
22
  </Provider>,
23
23
  );
24
24
  const json = component.toJSON();
25
- expect(json).toMatchSnapshot();
25
+ expect(json).toBeFalsy();
26
26
  });
27
27
 
28
28
  it('renders a datetime view widget component with a date and time', () => {
@@ -1,3 +1,4 @@
1
1
  export default function ImageViewWidget({ value }) {
2
+ // eslint-disable-next-line no-restricted-syntax
2
3
  return <img src={value?.download} alt={value?.filename} />;
3
4
  }
@@ -1,10 +1,11 @@
1
1
  import React, { useEffect, useCallback } from 'react';
2
2
  import { useSelector, useDispatch } from 'react-redux';
3
3
  import { v4 as uuid } from 'uuid';
4
- import { Icon, FormFieldWrapper } from '@plone/volto/components';
4
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
5
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
5
6
  import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
6
7
  import { Accordion, Button, Segment, Form, Dropdown } from 'semantic-ui-react';
7
- import { getNavigation } from '@plone/volto/actions';
8
+ import { getNavigation } from '@plone/volto/actions/navigation/navigation';
8
9
  import { defineMessages, useIntl } from 'react-intl';
9
10
  import config from '@plone/volto/registry';
10
11
 
@@ -13,6 +14,8 @@ import { numbersToMenuItemColumns } from '@eeacms/volto-eea-design-system/ui/Hea
13
14
  import upSVG from '@plone/volto/icons/up-key.svg';
14
15
  import downSVG from '@plone/volto/icons/down-key.svg';
15
16
 
17
+ const EMPTY_NAVIGATION = [];
18
+
16
19
  const messages = defineMessages({
17
20
  loadNavigationRoutes: {
18
21
  id: 'Load Main Navigation Routes',
@@ -257,7 +260,8 @@ const NavigationBehaviorWidget = (props) => {
257
260
  const { value = '{}', id, onChange } = props;
258
261
  const intl = useIntl();
259
262
  const dispatch = useDispatch();
260
- const navigation = useSelector((state) => state.navigation?.items || []);
263
+ const navigation =
264
+ useSelector((state) => state.navigation?.items) || EMPTY_NAVIGATION;
261
265
  const navigationLoaded = useSelector((state) => state.navigation?.loaded);
262
266
 
263
267
  // Parse JSON string to object
@@ -9,14 +9,13 @@ import '@testing-library/jest-dom';
9
9
 
10
10
  const mockStore = configureStore([thunk]);
11
11
 
12
- // Mock the getNavigation action
13
12
  const mockGetNavigation = jest.fn(() => ({ type: 'GET_NAVIGATION' }));
14
- jest.mock('@plone/volto/actions', () => ({
13
+ jest.mock('@plone/volto/actions/navigation/navigation', () => ({
15
14
  getNavigation: mockGetNavigation,
16
15
  }));
17
16
 
18
- // Mock the config
19
17
  jest.mock('@plone/volto/registry', () => ({
18
+ __esModule: true,
20
19
  default: {
21
20
  settings: {
22
21
  menuItemsLayouts: {
@@ -42,60 +41,66 @@ jest.mock('uuid', () => ({
42
41
  v4: () => 'test-uuid-123',
43
42
  }));
44
43
 
45
- // Mock Volto components
46
- jest.mock('@plone/volto/components', () => ({
47
- Icon: ({ name, size }) => (
44
+ jest.mock('@plone/volto/components/theme/Icon/Icon', () => ({
45
+ __esModule: true,
46
+ default: ({ name, size }) => (
48
47
  <div data-testid="icon" data-name={name} data-size={size} />
49
48
  ),
50
- FormFieldWrapper: ({ children, ...props }) => (
49
+ }));
50
+
51
+ jest.mock('@plone/volto/components/manage/Widgets/FormFieldWrapper', () => ({
52
+ __esModule: true,
53
+ default: ({ children, ...props }) => (
51
54
  <div data-testid="form-field-wrapper" {...props}>
52
55
  {children}
53
56
  </div>
54
57
  ),
55
58
  }));
56
59
 
57
- // Mock ObjectWidget
58
60
  jest.mock('@plone/volto/components/manage/Widgets/ObjectWidget', () => {
59
- return function MockObjectWidget({ id, schema, value, onChange }) {
60
- return (
61
- <div data-testid="object-widget" data-id={id}>
62
- {schema.properties.hideChildrenFromNavigation && (
63
- <div>
64
- <label>Hide Children From Navigation</label>
65
- <input
66
- type="checkbox"
67
- checked={value.hideChildrenFromNavigation || false}
68
- onChange={(e) =>
69
- onChange(id, {
70
- ...value,
71
- hideChildrenFromNavigation: e.target.checked,
72
- })
73
- }
74
- />
75
- </div>
76
- )}
77
- {schema.properties.menuItemColumns && (
78
- <div>
79
- <label>Menu Item Columns</label>
80
- <div data-testid="menu-item-columns">
81
- {(value.menuItemColumns || []).map((col, index) => (
82
- <span key={index}>{col}</span>
83
- ))}
61
+ return {
62
+ __esModule: true,
63
+ default: function MockObjectWidget({ id, schema, value, onChange }) {
64
+ return (
65
+ <div data-testid="object-widget" data-id={id}>
66
+ {schema.properties.hideChildrenFromNavigation && (
67
+ <div>
68
+ <label>Hide Children From Navigation</label>
69
+ <input
70
+ type="checkbox"
71
+ checked={value.hideChildrenFromNavigation || false}
72
+ onChange={(e) =>
73
+ onChange(id, {
74
+ ...value,
75
+ hideChildrenFromNavigation: e.target.checked,
76
+ })
77
+ }
78
+ />
84
79
  </div>
85
- </div>
86
- )}
87
- {schema.properties.menuItemChildrenListColumns && (
88
- <div>
89
- <label>Menu Item Children List Columns</label>
90
- <div data-testid="menu-item-children-columns">
91
- {(value.menuItemChildrenListColumns || []).map((col, index) => (
92
- <span key={index}>{col}</span>
93
- ))}
80
+ )}
81
+ {schema.properties.menuItemColumns && (
82
+ <div>
83
+ <label>Menu Item Columns</label>
84
+ <div data-testid="menu-item-columns">
85
+ {(value.menuItemColumns || []).map((col, index) => (
86
+ <span key={index}>{col}</span>
87
+ ))}
88
+ </div>
94
89
  </div>
95
- </div>
96
- )}
97
- </div>
98
- );
90
+ )}
91
+ {schema.properties.menuItemChildrenListColumns && (
92
+ <div>
93
+ <label>Menu Item Children List Columns</label>
94
+ <div data-testid="menu-item-children-columns">
95
+ {(value.menuItemChildrenListColumns || []).map((col, index) => (
96
+ <span key={index}>{col}</span>
97
+ ))}
98
+ </div>
99
+ </div>
100
+ )}
101
+ </div>
102
+ );
103
+ },
99
104
  };
100
105
  });
101
106
 
@@ -16,14 +16,17 @@ import {
16
16
  } from '@plone/volto/components/manage/Widgets/SelectUtils';
17
17
  import checkSVG from '@plone/volto/icons/check.svg';
18
18
  import checkBlankSVG from '@plone/volto/icons/check-blank.svg';
19
- import { Icon } from '@plone/volto/components';
19
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
20
20
 
21
21
  import {
22
22
  getVocabFromHint,
23
23
  getVocabFromField,
24
24
  getVocabFromItems,
25
- } from '@plone/volto/helpers';
26
- import { getVocabulary, getVocabularyTokenTitle } from '@plone/volto/actions';
25
+ } from '@plone/volto/helpers/Vocabularies/Vocabularies';
26
+ import {
27
+ getVocabulary,
28
+ getVocabularyTokenTitle,
29
+ } from '@plone/volto/actions/vocabularies/vocabularies';
27
30
 
28
31
  import {
29
32
  ClearIndicator,
@@ -34,7 +37,7 @@ import {
34
37
  MenuList,
35
38
  } from '@plone/volto/components/manage/Widgets/SelectStyling';
36
39
 
37
- import { FormFieldWrapper } from '@plone/volto/components';
40
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
38
41
 
39
42
  const messages = defineMessages({
40
43
  select: {
@@ -319,12 +322,12 @@ export default compose(
319
322
  return props.items?.choices
320
323
  ? { choices: props.items.choices, lang: state.intl.locale }
321
324
  : vocabState
322
- ? {
323
- choices: vocabState,
324
- vocabBaseUrl,
325
- lang: state.intl.locale,
326
- }
327
- : { vocabBaseUrl, lang: state.intl.locale };
325
+ ? {
326
+ choices: vocabState,
327
+ vocabBaseUrl,
328
+ lang: state.intl.locale,
329
+ }
330
+ : { vocabBaseUrl, lang: state.intl.locale };
328
331
  },
329
332
  { getVocabulary, getVocabularyTokenTitle },
330
333
  ),
@@ -6,7 +6,7 @@
6
6
  import React, { useState, useMemo } from 'react';
7
7
  import PropTypes from 'prop-types';
8
8
  import { Table } from 'semantic-ui-react';
9
- import { map } from 'lodash';
9
+ import map from 'lodash/map';
10
10
  import {
11
11
  serializeNodes,
12
12
  serializeNodesToText,
@@ -80,8 +80,8 @@ const View = ({ data }) => {
80
80
  state.column !== index
81
81
  ? 'ascending'
82
82
  : state.direction === 'ascending'
83
- ? 'descending'
84
- : 'ascending',
83
+ ? 'descending'
84
+ : 'ascending',
85
85
  });
86
86
  };
87
87
 
@@ -3,9 +3,9 @@ import {
3
3
  serializeNodesToText,
4
4
  } from '@plone/volto-slate/editor/render';
5
5
  import config from '@plone/volto/registry';
6
- import { isEqual } from 'lodash';
6
+ import isEqual from 'lodash/isEqual';
7
7
  import Slugger from 'github-slugger';
8
- import { normalizeString } from '@plone/volto/helpers';
8
+ import { normalizeString } from '@plone/volto/helpers/Utils/Utils';
9
9
 
10
10
  const TextBlockView = (props) => {
11
11
  const { id, data, styling = {} } = props;
@@ -1,6 +1,7 @@
1
1
  import ReactDOM from 'react-dom';
2
2
  import cx from 'classnames';
3
- import { isEqual, cloneDeep } from 'lodash';
3
+ import isEqual from 'lodash/isEqual';
4
+ import cloneDeep from 'lodash/cloneDeep';
4
5
  import { Transforms, Editor, Point } from 'slate'; // , Transforms
5
6
  import { Slate, Editable, ReactEditor } from 'slate-react';
6
7
  import React, { Component } from 'react'; // , useState
@@ -81,16 +82,14 @@ class SlateEditor extends Component {
81
82
  this.handleChange = this.handleChange.bind(this);
82
83
  this.getSavedSelection = this.getSavedSelection.bind(this);
83
84
  this.setSavedSelection = this.setSavedSelection.bind(this);
85
+ this.getEditorValue = this.getEditorValue.bind(this);
84
86
 
85
87
  this.savedSelection = null;
86
88
 
87
89
  const uid = uuid(); // used to namespace the editor's plugins
88
90
 
89
91
  this.slateSettings = props.slateSettings || config.settings.slate;
90
- this.initialValue =
91
- this.props.value && this.props.value.length > 0
92
- ? cloneDeep(this.props.value)
93
- : this.slateSettings.defaultValue();
92
+ this.initialValue = this.getEditorValue(this.props.value);
94
93
 
95
94
  this.state = {
96
95
  editor: this.createEditor(uid),
@@ -103,6 +102,21 @@ class SlateEditor extends Component {
103
102
  this.selectionTimeout = null;
104
103
  }
105
104
 
105
+ getEditorValue(value = this.props.value) {
106
+ if (Array.isArray(value) && value.length > 0) {
107
+ return cloneDeep(value);
108
+ }
109
+
110
+ return (
111
+ this.slateSettings.defaultValue?.() || [
112
+ {
113
+ type: 'p',
114
+ children: [{ text: '' }],
115
+ },
116
+ ]
117
+ );
118
+ }
119
+
106
120
  getSavedSelection() {
107
121
  return this.savedSelection;
108
122
  }
@@ -183,10 +197,7 @@ class SlateEditor extends Component {
183
197
  !isEqual(this.props.value, this.state.internalValue)
184
198
  ) {
185
199
  const { editor } = this.state;
186
- const newValue =
187
- this.props.value && this.props.value.length > 0
188
- ? cloneDeep(this.props.value)
189
- : this.slateSettings.defaultValue();
200
+ const newValue = this.getEditorValue(this.props.value);
190
201
 
191
202
  resetNodes(editor, { nodes: newValue });
192
203
 
@@ -239,6 +250,7 @@ class SlateEditor extends Component {
239
250
 
240
251
  render() {
241
252
  const {
253
+ id,
242
254
  selected,
243
255
  placeholder,
244
256
  onKeyDown,
@@ -290,7 +302,7 @@ class SlateEditor extends Component {
290
302
  <EditorContext.Provider value={editor}>
291
303
  <Slate
292
304
  editor={editor}
293
- initialValue={this.initialValue}
305
+ initialValue={this.getEditorValue()}
294
306
  onChange={this.handleChange}
295
307
  >
296
308
  {selected ? (
@@ -367,6 +379,7 @@ class SlateEditor extends Component {
367
379
  if (handled) return;
368
380
  onKeyDown && onKeyDown({ editor, event });
369
381
  }}
382
+ aria-labelledby={id ? `field-${id}` : undefined}
370
383
  {...editableProps}
371
384
  />
372
385
  {selected &&
@@ -6,9 +6,13 @@ import { useIntl } from 'react-intl';
6
6
  import { useSelector } from 'react-redux';
7
7
  import { Node, Text } from 'slate';
8
8
  import cx from 'classnames';
9
- import { isEmpty, isEqual, omit } from 'lodash';
10
- import { UniversalLink, Toast } from '@plone/volto/components';
11
- import { messages, addAppURL } from '@plone/volto/helpers';
9
+ import isEmpty from 'lodash/isEmpty';
10
+ import isEqual from 'lodash/isEqual';
11
+ import omit from 'lodash/omit';
12
+ import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
13
+ import Toast from '@plone/volto/components/manage/Toast/Toast';
14
+ import { messages } from '@plone/volto/helpers//MessageLabels/MessageLabels';
15
+ import { addAppURL } from '@plone/volto/helpers/Url/Url';
12
16
  import useClipboard from '@plone/volto/hooks/clipboard/useClipboard';
13
17
  import config from '@plone/volto/registry';
14
18
  import linkSVG from '@plone/volto/icons/link.svg';
@@ -4,8 +4,11 @@ import config from '@plone/volto/registry';
4
4
  import {
5
5
  getBlocksFieldname,
6
6
  getBlocksLayoutFieldname,
7
- } from '@plone/volto/helpers';
8
- import _ from 'lodash';
7
+ } from '@plone/volto/helpers/Blocks/Blocks';
8
+ import find from 'lodash/find';
9
+ import first from 'lodash/first';
10
+ import includes from 'lodash/includes';
11
+ import some from 'lodash/some';
9
12
  import { makeEditor } from '@plone/volto-slate/utils/editor';
10
13
 
11
14
  // case sensitive; first in an inner array is the default and preffered format
@@ -138,10 +141,10 @@ export const isSingleBlockTypeActive = (editor, format) => {
138
141
  };
139
142
 
140
143
  export const isBlockActive = (editor, format) => {
141
- const aliasList = _.find(formatAliases, (x) => _.includes(x, format));
144
+ const aliasList = find(formatAliases, (x) => includes(x, format));
142
145
 
143
146
  if (aliasList) {
144
- const aliasFound = _.some(aliasList, (y) => {
147
+ const aliasFound = some(aliasList, (y) => {
145
148
  return isSingleBlockTypeActive(editor, y);
146
149
  });
147
150
 
@@ -156,17 +159,17 @@ export const isBlockActive = (editor, format) => {
156
159
  export const getBlockTypeContextData = (editor, format) => {
157
160
  let isActive, defaultFormat, matcher;
158
161
 
159
- const aliasList = _.find(formatAliases, (x) => _.includes(x, format));
162
+ const aliasList = find(formatAliases, (x) => includes(x, format));
160
163
 
161
164
  if (aliasList) {
162
- const aliasFound = _.some(aliasList, (y) => {
165
+ const aliasFound = some(aliasList, (y) => {
163
166
  return isSingleBlockTypeActive(editor, y);
164
167
  });
165
168
 
166
169
  if (aliasFound) {
167
170
  isActive = true;
168
- defaultFormat = _.first(aliasList);
169
- matcher = (n) => _.includes(aliasList, n.type);
171
+ defaultFormat = first(aliasList);
172
+ matcher = (n) => includes(aliasList, n.type);
170
173
 
171
174
  return { isActive, defaultFormat, matcher };
172
175
  }
@@ -1,7 +1,7 @@
1
1
  import { Grid } from 'semantic-ui-react';
2
2
  import cx from 'classnames';
3
- import { RenderBlocks } from '@plone/volto/components';
4
- import { withBlockExtensions } from '@plone/volto/helpers';
3
+ import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
4
+ import { withBlockExtensions } from '@plone/volto/helpers//Extensions';
5
5
  import config from '@plone/volto/registry';
6
6
 
7
7
  const convertTeaserToGridIfNecessaryAndTransformEmptyBlocksToSlate = (data) => {
@@ -2,7 +2,6 @@
2
2
  * Edit image block.
3
3
  * @module components/manage/Blocks/Image/Edit
4
4
  */
5
-
6
5
  import React, { Component } from 'react';
7
6
  import PropTypes from 'prop-types';
8
7
  import { connect } from 'react-redux';
@@ -12,20 +11,22 @@ import { Button, Dimmer, Input, Loader, Message } from 'semantic-ui-react';
12
11
  import { defineMessages, injectIntl } from 'react-intl';
13
12
  import loadable from '@loadable/component';
14
13
  import cx from 'classnames';
15
- import { isEqual } from 'lodash';
14
+ import isEqual from 'lodash/isEqual';
16
15
 
17
- import { Icon, ImageSidebar, SidebarPortal } from '@plone/volto/components';
16
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
17
+ import ImageSidebar from '@plone/volto/components/manage/Blocks/Image/ImageSidebar';
18
+ import SidebarPortal from '@plone/volto/components/manage/Sidebar/SidebarPortal';
18
19
  import { Icon as IconSemantic } from 'semantic-ui-react';
19
- import { createContent } from '@plone/volto/actions';
20
- import { Copyright } from '@eeacms/volto-eea-design-system/ui';
20
+ import { createContent } from '@plone/volto/actions/content/content';
21
+ import Copyright from '@eeacms/volto-eea-design-system/ui/Copyright/Copyright';
21
22
 
22
23
  import {
23
24
  flattenToAppURL,
24
25
  getBaseUrl,
25
26
  isInternalURL,
26
- withBlockExtensions,
27
- validateFileUploadSize,
28
- } from '@plone/volto/helpers';
27
+ } from '@plone/volto/helpers/Url/Url';
28
+ import { withBlockExtensions } from '@plone/volto/helpers//Extensions';
29
+ import { validateFileUploadSize } from '@plone/volto/helpers//FormValidation/FormValidation';
29
30
  import config from '@plone/volto/registry';
30
31
 
31
32
  import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
@@ -271,6 +272,7 @@ class Edit extends Component {
271
272
  this.props.data.placeholder ||
272
273
  this.props.intl.formatMessage(messages.ImageBlockInputPlaceholder);
273
274
  const { copyright, copyrightIcon, copyrightPosition } = data;
275
+ const resolvedCopyrightPosition = copyrightPosition || 'left';
274
276
 
275
277
  const showCopyright = data?.size === 'l' || !data.size;
276
278
 
@@ -321,36 +323,36 @@ class Edit extends Component {
321
323
  data.image_scales
322
324
  ? undefined
323
325
  : isInternalURL(data.url)
324
- ? // Backwards compat in the case that the block is storing the full server URL
325
- (() => {
326
- if (data.size === 'l')
326
+ ? // Backwards compat in the case that the block is storing the full server URL
327
+ (() => {
328
+ if (data.size === 'l')
329
+ return `${flattenToAppURL(
330
+ data.url,
331
+ )}/@@images/image/large`;
332
+ if (data.size === 'm')
333
+ return `${flattenToAppURL(
334
+ data.url,
335
+ )}/@@images/image/preview`;
336
+ if (data.size === 's')
337
+ return `${flattenToAppURL(
338
+ data.url,
339
+ )}/@@images/image/mini`;
327
340
  return `${flattenToAppURL(
328
341
  data.url,
329
342
  )}/@@images/image/large`;
330
- if (data.size === 'm')
331
- return `${flattenToAppURL(
332
- data.url,
333
- )}/@@images/image/preview`;
334
- if (data.size === 's')
335
- return `${flattenToAppURL(
336
- data.url,
337
- )}/@@images/image/mini`;
338
- return `${flattenToAppURL(
339
- data.url,
340
- )}/@@images/image/large`;
341
- })()
342
- : data.url
343
+ })()
344
+ : data.url
343
345
  }
344
346
  sizes={config.blocks.blocksConfig.image.getSizes(data)}
345
347
  alt={data.alt || ''}
346
348
  loading="lazy"
347
349
  responsive={true}
348
350
  />
349
- <div className={`copyright-wrapper ${copyrightPosition}`}>
351
+ <div className={`copyright-wrapper ${resolvedCopyrightPosition}`}>
350
352
  {copyright && showCopyright ? (
351
- <Copyright copyrightPosition={copyrightPosition}>
353
+ <Copyright copyrightPosition={resolvedCopyrightPosition}>
352
354
  <Copyright.Icon>
353
- <IconSemantic name={copyrightIcon} />
355
+ <IconSemantic className={copyrightIcon} />
354
356
  </Copyright.Icon>
355
357
  <Copyright.Text>{copyright}</Copyright.Text>
356
358
  </Copyright>
@@ -383,6 +385,7 @@ class Edit extends Component {
383
385
  </Dimmer>
384
386
  )}
385
387
  <div className="no-image-wrapper">
388
+ {/* eslint-disable-next-line no-restricted-syntax */}
386
389
  <img src={imageBlockSVG} alt="" />
387
390
  <div className="toolbar-inner">
388
391
  <Button.Group>