@plone/volto 16.7.0 → 16.8.1

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.
package/.changelog.draft CHANGED
@@ -1,25 +1,6 @@
1
- ## 16.7.0 (2023-01-11)
2
-
3
- ### Feature
4
-
5
- - Show project name and version in control panel @sneridagh [#4176](https://github.com/plone/volto/issues/4176)
6
- - Enhance Cypress content creation command @sneridagh [#4210](https://github.com/plone/volto/issues/4210)
1
+ ## 16.8.1 (2023-01-18)
7
2
 
8
3
  ### Bugfix
9
4
 
10
- - Improve matching in keyboard slash menu. [davisagli] [#4187](https://github.com/plone/volto/issues/4187)
11
- - (fix): sidebar is not displaying correctly when clicking on a lead image field. @dobri1408 [#4191](https://github.com/plone/volto/issues/4191)
12
- - Cleanup `package.json` scripts section @sneridagh [#4193](https://github.com/plone/volto/issues/4193)
13
- - Fixed condition to select without vocabulary @SaraBianchi [#4200](https://github.com/plone/volto/issues/4200)
14
- - fix iframe covering the page due to a react-error-overlay bug @reebalazs [#4242](https://github.com/plone/volto/issues/4242)
15
-
16
- ### Documentation
17
-
18
- - Add description for different types of blocks. @MAX-786 [#3827](https://github.com/plone/volto/issues/3827)
19
- - Update makefile to use Vale for spell, grammar, and style checking. Fix linkcheckbroken to return the correct exit code for broken links. Fix broken links. [stevepiercy] [#4181](https://github.com/plone/volto/issues/4181)
20
- - Add todo regarding management of Plone's backend. Update versions. [stevepiercy] [#4198](https://github.com/plone/volto/issues/4198)
21
- - Pin Sphinx<5,>=3 due to sphinx-book-theme 0.3.3 requirement. [stevepiercy] [#4199](https://github.com/plone/volto/issues/4199)
22
- - Add message about the status of Volto and Plone 6 Installation docs, directing the reader to the main Plone 6 docs. [stevepiercy] [#4209](https://github.com/plone/volto/issues/4209)
23
- - Clean up Glossary and integrate with main docs. See https://github.com/plone/documentation/issues/1415. [stevepiercy] [#4211](https://github.com/plone/volto/issues/4211)
24
- - Add some instructions for dealing with untranspiled add-ons and a lazy loading example for functional components. [cguardia] [#4233](https://github.com/plone/volto/issues/4233)
5
+ - Fix StyleWrapper extenders, the classNames were not being re-fed into the pipe @sneridagh [#4275](https://github.com/plone/volto/issues/4275)
25
6
 
package/CHANGELOG.md CHANGED
@@ -8,6 +8,29 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 16.8.1 (2023-01-18)
12
+
13
+ ### Bugfix
14
+
15
+ - Fix StyleWrapper extenders, the classNames were not being re-fed into the pipe @sneridagh [#4275](https://github.com/plone/volto/issues/4275)
16
+
17
+
18
+ ## 16.8.0 (2023-01-18)
19
+
20
+ ### Feature
21
+
22
+ - Autocomplete widget support for QueryStringWidget @sneridagh [#4177](https://github.com/plone/volto/issues/4177)
23
+ - 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)
24
+
25
+ ### Bugfix
26
+
27
+ - Fix typo in 4260 @sneridagh [#4268](https://github.com/plone/volto/issues/4268)
28
+
29
+ ### Documentation
30
+
31
+ - Update links to docs to use correct versions. [stevepiercy] [#4256](https://github.com/plone/volto/issues/4256)
32
+
33
+
11
34
  ## 16.7.0 (2023-01-11)
12
35
 
13
36
  ### Feature
@@ -17,6 +40,7 @@
17
40
 
18
41
  ### Bugfix
19
42
 
43
+ - Use Grid instead of Table in Diffview @erral
20
44
  - Improve matching in keyboard slash menu. [davisagli] [#4187](https://github.com/plone/volto/issues/4187)
21
45
  - (fix): sidebar is not displaying correctly when clicking on a lead image field. @dobri1408 [#4191](https://github.com/plone/volto/issues/4191)
22
46
  - Cleanup `package.json` scripts section @sneridagh [#4193](https://github.com/plone/volto/issues/4193)
package/README.md CHANGED
@@ -278,7 +278,7 @@ make start-backend-docker
278
278
 
279
279
  or running Plone on your machine (advanced), additional dependencies might be
280
280
  required, only for Plone experienced integrators/developers. Check the [Plone
281
- Installation Documentation](https://docs.plone.org/manage/installing/installation.html).
281
+ Installation Documentation](https://6.docs.plone.org/install/index.html).
282
282
 
283
283
  ```shell
284
284
  make build-backend
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.7.0",
12
+ "version": "16.8.1",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.7.0",
3
+ "version": "16.8.1",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -1,15 +1,26 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
- import { buildStyleClassNamesFromData } from '@plone/volto/helpers';
3
+ import {
4
+ buildStyleClassNamesFromData,
5
+ buildStyleClassNamesExtenders,
6
+ } from '@plone/volto/helpers';
4
7
 
5
8
  const StyleWrapper = (props) => {
6
- const { children, data = {} } = props;
7
- const styles = buildStyleClassNamesFromData(data.styles);
9
+ let classNames = [];
10
+ const { children, content, data = {}, block } = props;
11
+ classNames = buildStyleClassNamesFromData(data.styles);
12
+
13
+ classNames = buildStyleClassNamesExtenders({
14
+ block,
15
+ content,
16
+ data,
17
+ classNames,
18
+ });
8
19
  const rewrittenChildren = React.Children.map(children, (child) => {
9
20
  if (React.isValidElement(child)) {
10
21
  const childProps = {
11
22
  ...props,
12
- className: cx([child.props.className, ...styles]),
23
+ className: cx([child.props.className, ...classNames]),
13
24
  };
14
25
  return React.cloneElement(child, childProps);
15
26
  }
@@ -14,6 +14,7 @@ import { getQuerystring } from '@plone/volto/actions';
14
14
  import { Icon } from '@plone/volto/components';
15
15
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
16
16
  import cx from 'classnames';
17
+ import config from '@plone/volto/registry';
17
18
 
18
19
  import {
19
20
  Option,
@@ -193,6 +194,23 @@ export class QuerystringWidgetComponent extends Component {
193
194
  />
194
195
  </Form.Field>
195
196
  );
197
+ case 'autocomplete':
198
+ const AutoCompleteComponent = config.widgets.widget.autocomplete;
199
+ const vocabulary = { '@id': this.props.indexes[row.i].vocabulary };
200
+ return (
201
+ <Form.Field style={{ flex: '1 0 auto', maxWidth: '92%' }}>
202
+ <AutoCompleteComponent
203
+ {...props}
204
+ vocabulary={vocabulary}
205
+ wrapped={false}
206
+ id={`id-${index}`}
207
+ title={`title-${index}`}
208
+ onChange={(_d, data) => {
209
+ this.onChangeValue(index, data);
210
+ }}
211
+ />
212
+ </Form.Field>
213
+ );
196
214
  case 'ReferenceWidget':
197
215
  default:
198
216
  // if (row.o === 'plone.app.querystring.operation.string.relativePath') {
@@ -7,3 +7,5 @@ export const styleClassNameConverters = {
7
7
  noprefix: (name, value) => value,
8
8
  bool: (name, value) => (value ? name : ''),
9
9
  };
10
+
11
+ export const styleClassNameExtenders = [];
@@ -24,7 +24,7 @@ import { loadables } from './Loadables';
24
24
  import { workflowMapping } from './Workflows';
25
25
 
26
26
  import { contentIcons } from './ContentIcons';
27
- import { styleClassNameConverters } from './Style';
27
+ import { styleClassNameConverters, styleClassNameExtenders } from './Style';
28
28
  import {
29
29
  controlPanelsIcons,
30
30
  filterControlPanels,
@@ -169,6 +169,7 @@ let config = {
169
169
  workflowMapping,
170
170
  errorHandlers: [], // callables for unhandled errors
171
171
  styleClassNameConverters,
172
+ styleClassNameExtenders,
172
173
  },
173
174
  experimental: {
174
175
  addBlockButton: {
@@ -481,3 +481,46 @@ export const buildStyleClassNamesFromData = (obj = {}, prefix = '') => {
481
481
  )
482
482
  .filter((v) => !!v);
483
483
  };
484
+
485
+ /**
486
+ * Generate classNames from extenders
487
+ *
488
+ * @function buildStyleClassNamesExtenders
489
+ * @param {Object} params An object with data, content and block (current block id)
490
+ * @return {Array} Extender classNames resultant array
491
+ */
492
+ export const buildStyleClassNamesExtenders = ({
493
+ block,
494
+ content,
495
+ data,
496
+ classNames,
497
+ }) => {
498
+ return config.settings.styleClassNameExtenders.reduce(
499
+ (acc, extender) => extender({ block, content, data, classNames: acc }),
500
+ classNames,
501
+ );
502
+ };
503
+
504
+ /**
505
+ * Return previous/next blocks given the content object and the current block id
506
+ *
507
+ * @function getPreviousNextBlock
508
+ * @param {Object} params An object with the content object and block (current block id)
509
+ * @return {Array} An array with the signature [previousBlock, nextBlock]
510
+ */
511
+ export const getPreviousNextBlock = ({ content, block }) => {
512
+ const previousBlock =
513
+ content['blocks'][
514
+ content['blocks_layout'].items[
515
+ content['blocks_layout'].items.indexOf(block) - 1
516
+ ]
517
+ ];
518
+ const nextBlock =
519
+ content['blocks'][
520
+ content['blocks_layout'].items[
521
+ content['blocks_layout'].items.indexOf(block) + 1
522
+ ]
523
+ ];
524
+
525
+ return [previousBlock, nextBlock];
526
+ };
@@ -17,6 +17,8 @@ import {
17
17
  applyBlockDefaults,
18
18
  applySchemaDefaults,
19
19
  buildStyleClassNamesFromData,
20
+ buildStyleClassNamesExtenders,
21
+ getPreviousNextBlock,
20
22
  } from './Blocks';
21
23
 
22
24
  import config from '@plone/volto/registry';
@@ -938,4 +940,289 @@ describe('Blocks', () => {
938
940
  expect(buildStyleClassNamesFromData(styles)).toEqual([]);
939
941
  });
940
942
  });
943
+
944
+ describe('getPreviousNextBlock', () => {
945
+ it('basic functionality', () => {
946
+ const content = {
947
+ blocks: {
948
+ 1: {
949
+ '@type': 'slate',
950
+ styles: {
951
+ backgroundColor: 'grey',
952
+ },
953
+ },
954
+ 2: {
955
+ '@type': 'slate',
956
+ },
957
+ 3: {
958
+ '@type': 'slate',
959
+ styles: {
960
+ backgroundColor: 'grey',
961
+ },
962
+ },
963
+ },
964
+ blocks_layout: {
965
+ items: [1, 2, 3],
966
+ },
967
+ };
968
+ const block = 2;
969
+ const [previousBlock, nextBlock] = getPreviousNextBlock({
970
+ content,
971
+ block,
972
+ });
973
+ expect(previousBlock).toEqual({
974
+ '@type': 'slate',
975
+ styles: {
976
+ backgroundColor: 'grey',
977
+ },
978
+ });
979
+ expect(nextBlock).toEqual({
980
+ '@type': 'slate',
981
+ styles: {
982
+ backgroundColor: 'grey',
983
+ },
984
+ });
985
+ });
986
+ });
987
+
988
+ describe('buildStyleClassNamesExtenders', () => {
989
+ beforeAll(() => {
990
+ // Example styleClassNameExtenders
991
+ config.settings.styleClassNameExtenders = [
992
+ ({ block, content, data, classNames }) => {
993
+ let styles = [];
994
+ const [previousBlock, nextBlock] = getPreviousNextBlock({
995
+ content,
996
+ block,
997
+ });
998
+
999
+ if (nextBlock?.['@type']) {
1000
+ styles.push(`next--is--${nextBlock['@type']}`);
1001
+ }
1002
+
1003
+ if (data?.['@type'] === previousBlock?.['@type']) {
1004
+ styles.push('previous--is--same--block-type');
1005
+ }
1006
+
1007
+ if (data?.['@type'] === nextBlock?.['@type']) {
1008
+ styles.push('next--is--same--block-type');
1009
+ }
1010
+
1011
+ if (data?.['@type'] !== previousBlock?.['@type']) {
1012
+ styles.push('is--first--of--block-type');
1013
+ }
1014
+
1015
+ if (data?.['@type'] !== nextBlock?.['@type']) {
1016
+ styles.push('is--last--of--block-type');
1017
+ }
1018
+
1019
+ const previousColor =
1020
+ previousBlock?.styles?.backgroundColor ?? 'transparent';
1021
+ const currentColor = data?.styles?.backgroundColor ?? 'transparent';
1022
+ const nextColor = nextBlock?.styles?.backgroundColor ?? 'transparent';
1023
+
1024
+ if (currentColor === previousColor) {
1025
+ styles.push('previous--has--same--backgroundColor');
1026
+ } else if (currentColor !== previousColor) {
1027
+ styles.push('previous--has--different--backgroundColor');
1028
+ }
1029
+
1030
+ if (currentColor === nextColor) {
1031
+ styles.push('next--has--same--backgroundColor');
1032
+ } else if (currentColor !== nextColor) {
1033
+ styles.push('next--has--different--backgroundColor');
1034
+ }
1035
+
1036
+ return [...classNames, ...styles];
1037
+ },
1038
+ ];
1039
+ });
1040
+
1041
+ it('slate grey + slate + slate grey ', () => {
1042
+ const content = {
1043
+ blocks: {
1044
+ 1: {
1045
+ '@type': 'slate',
1046
+ styles: {
1047
+ backgroundColor: 'grey',
1048
+ },
1049
+ },
1050
+ 2: {
1051
+ '@type': 'slate',
1052
+ },
1053
+ 3: {
1054
+ '@type': 'slate',
1055
+ styles: {
1056
+ backgroundColor: 'grey',
1057
+ },
1058
+ },
1059
+ },
1060
+ blocks_layout: {
1061
+ items: [1, 2, 3],
1062
+ },
1063
+ };
1064
+ const block = 2;
1065
+ const data = content['blocks'][2];
1066
+ const classNames = [];
1067
+ expect(
1068
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1069
+ ).toStrictEqual([
1070
+ 'next--is--slate',
1071
+ 'previous--is--same--block-type',
1072
+ 'next--is--same--block-type',
1073
+ 'previous--has--different--backgroundColor',
1074
+ 'next--has--different--backgroundColor',
1075
+ ]);
1076
+ });
1077
+
1078
+ it('slate grey + slate grey + slate grey ', () => {
1079
+ const content = {
1080
+ blocks: {
1081
+ 1: {
1082
+ '@type': 'slate',
1083
+ styles: {
1084
+ backgroundColor: 'grey',
1085
+ },
1086
+ },
1087
+ 2: {
1088
+ '@type': 'slate',
1089
+ styles: {
1090
+ backgroundColor: 'grey',
1091
+ },
1092
+ },
1093
+ 3: {
1094
+ '@type': 'slate',
1095
+ styles: {
1096
+ backgroundColor: 'grey',
1097
+ },
1098
+ },
1099
+ },
1100
+ blocks_layout: {
1101
+ items: [1, 2, 3],
1102
+ },
1103
+ };
1104
+ const block = 2;
1105
+ const data = content['blocks'][2];
1106
+ const classNames = [];
1107
+
1108
+ expect(
1109
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1110
+ ).toStrictEqual([
1111
+ 'next--is--slate',
1112
+ 'previous--is--same--block-type',
1113
+ 'next--is--same--block-type',
1114
+ 'previous--has--same--backgroundColor',
1115
+ 'next--has--same--backgroundColor',
1116
+ ]);
1117
+ });
1118
+
1119
+ it('grid + slate grey + slate grey ', () => {
1120
+ const content = {
1121
+ blocks: {
1122
+ 1: {
1123
+ '@type': '__grid',
1124
+ },
1125
+ 2: {
1126
+ '@type': 'slate',
1127
+ styles: {
1128
+ backgroundColor: 'grey',
1129
+ },
1130
+ },
1131
+ 3: {
1132
+ '@type': 'slate',
1133
+ styles: {
1134
+ backgroundColor: 'grey',
1135
+ },
1136
+ },
1137
+ },
1138
+ blocks_layout: {
1139
+ items: [1, 2, 3],
1140
+ },
1141
+ };
1142
+ const block = 2;
1143
+ const data = content['blocks'][2];
1144
+ const classNames = [];
1145
+
1146
+ expect(
1147
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1148
+ ).toStrictEqual([
1149
+ 'next--is--slate',
1150
+ 'next--is--same--block-type',
1151
+ 'is--first--of--block-type',
1152
+ 'previous--has--different--backgroundColor',
1153
+ 'next--has--same--backgroundColor',
1154
+ ]);
1155
+ });
1156
+
1157
+ it('grid + grid + slate grey ', () => {
1158
+ const content = {
1159
+ blocks: {
1160
+ 1: {
1161
+ '@type': '__grid',
1162
+ },
1163
+ 2: {
1164
+ '@type': '__grid',
1165
+ },
1166
+ 3: {
1167
+ '@type': 'slate',
1168
+ styles: {
1169
+ backgroundColor: 'grey',
1170
+ },
1171
+ },
1172
+ },
1173
+ blocks_layout: {
1174
+ items: [1, 2, 3],
1175
+ },
1176
+ };
1177
+ const block = 2;
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'];
1215
+
1216
+ expect(
1217
+ buildStyleClassNamesExtenders({ block, content, data, classNames }),
1218
+ ).toStrictEqual([
1219
+ 'has--align--center',
1220
+ 'next--is--slate',
1221
+ 'previous--is--same--block-type',
1222
+ 'is--last--of--block-type',
1223
+ 'previous--has--same--backgroundColor',
1224
+ 'next--has--different--backgroundColor',
1225
+ ]);
1226
+ });
1227
+ });
941
1228
  });
@@ -56,6 +56,8 @@ export {
56
56
  applyBlockDefaults,
57
57
  applySchemaDefaults,
58
58
  buildStyleClassNamesFromData,
59
+ buildStyleClassNamesExtenders,
60
+ getPreviousNextBlock,
59
61
  } from '@plone/volto/helpers/Blocks/Blocks';
60
62
  export BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
61
63
  export ScrollToTop from '@plone/volto/helpers/ScrollToTop/ScrollToTop';
@@ -20,7 +20,10 @@ import {
20
20
  } from '@plone/volto/config/RichTextEditor/Blocks';
21
21
  import FromHTMLCustomBlockFn from '@plone/volto/config/RichTextEditor/FromHTML';
22
22
  import { contentIcons } from '@plone/volto/config/ContentIcons';
23
- import { styleClassNameConverters } from '@plone/volto/config/Style';
23
+ import {
24
+ styleClassNameConverters,
25
+ styleClassNameExtenders,
26
+ } from '@plone/volto/config/Style';
24
27
 
25
28
  import {
26
29
  controlPanelsIcons,
@@ -76,6 +79,7 @@ config.set('settings', {
76
79
  downloadableObjects: ['File'],
77
80
  viewableInBrowserObjects: [],
78
81
  styleClassNameConverters,
82
+ styleClassNameExtenders,
79
83
  });
80
84
  config.set('blocks', {
81
85
  blocksConfig: {
package/news/4160.bug DELETED
@@ -1,2 +0,0 @@
1
- Use Grid instead of Table in Diffview
2
- [erral]