@plone/volto 18.15.1 → 18.17.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.
- package/CHANGELOG.md +17 -0
- package/package.json +4 -3
- package/src/components/manage/Blocks/Block/BlocksForm.jsx +1 -0
- package/src/components/manage/Blocks/Block/Edit.jsx +2 -1
- package/src/components/manage/Blocks/Block/StyleWrapper.jsx +11 -3
- package/vite-plugins/{svg.js → svg.mjs} +1 -1
- package/{vitest.config.ts → vitest.config.mjs} +25 -9
- package/src/components/manage/Widgets/FileWidget.test.jsx +0 -123
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,23 @@ myst:
|
|
|
17
17
|
|
|
18
18
|
<!-- towncrier release notes start -->
|
|
19
19
|
|
|
20
|
+
## 18.17.0 (2025-05-06)
|
|
21
|
+
|
|
22
|
+
### Feature
|
|
23
|
+
|
|
24
|
+
- Added `contained` class if `isContainer` prop is passed (from containers). @sneridagh [#7043](https://github.com/plone/volto/issues/7043)
|
|
25
|
+
|
|
26
|
+
## 18.16.0 (2025-05-01)
|
|
27
|
+
|
|
28
|
+
### Feature
|
|
29
|
+
|
|
30
|
+
- Rename `vitest.config.ts` to `vitest.config.mjs` for allowing it to be loaded from add-ons. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
|
|
31
|
+
|
|
32
|
+
### Bugfix
|
|
33
|
+
|
|
34
|
+
- Added missing dependency for `sgvo`. Fixed `svgo` library loading in `./vite-plugins/svg.js`. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
|
|
35
|
+
- Rename `./vite-plugins/svg.js` to proper extension `vite-plugins/svg.mjs`. @sneridagh [#7035](https://github.com/plone/volto/issues/7035)
|
|
36
|
+
|
|
20
37
|
## 18.15.1 (2025-04-30)
|
|
21
38
|
|
|
22
39
|
### Internal
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "18.
|
|
12
|
+
"version": "18.17.0",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -237,8 +237,8 @@
|
|
|
237
237
|
"use-deep-compare-effect": "1.8.1",
|
|
238
238
|
"uuid": "^8.3.2",
|
|
239
239
|
"@plone/registry": "2.5.3",
|
|
240
|
-
"@plone/
|
|
241
|
-
"@plone/
|
|
240
|
+
"@plone/volto-slate": "18.3.0",
|
|
241
|
+
"@plone/scripts": "3.9.0"
|
|
242
242
|
},
|
|
243
243
|
"devDependencies": {
|
|
244
244
|
"@babel/core": "^7.0.0",
|
|
@@ -349,6 +349,7 @@
|
|
|
349
349
|
"stylelint-config-idiomatic-order": "10.0.0",
|
|
350
350
|
"stylelint-prettier": "5.0.0",
|
|
351
351
|
"svg-loader": "0.0.2",
|
|
352
|
+
"svgo": "^3.0.0",
|
|
352
353
|
"svgo-loader": "3.0.3",
|
|
353
354
|
"terser-webpack-plugin": "5.3.6",
|
|
354
355
|
"tmp": "0.2.1",
|
|
@@ -122,7 +122,7 @@ export class Edit extends Component {
|
|
|
122
122
|
*/
|
|
123
123
|
render() {
|
|
124
124
|
const { blocksConfig = config.blocks.blocksConfig } = this.props;
|
|
125
|
-
const { editable, type } = this.props;
|
|
125
|
+
const { editable, type, isContainer: parentIsContainer } = this.props;
|
|
126
126
|
|
|
127
127
|
const disableNewBlocks = this.props.data?.disableNewBlocks;
|
|
128
128
|
|
|
@@ -198,6 +198,7 @@ export class Edit extends Component {
|
|
|
198
198
|
{...this.props}
|
|
199
199
|
blockNode={this.blockNode}
|
|
200
200
|
data={this.props.data}
|
|
201
|
+
className={cx({ contained: parentIsContainer })}
|
|
201
202
|
/>
|
|
202
203
|
{this.props.manage && (
|
|
203
204
|
<SidebarPortal
|
|
@@ -9,7 +9,13 @@ import {
|
|
|
9
9
|
const StyleWrapper = (props) => {
|
|
10
10
|
let classNames,
|
|
11
11
|
style = [];
|
|
12
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
block,
|
|
14
|
+
children,
|
|
15
|
+
content,
|
|
16
|
+
data = {},
|
|
17
|
+
isContainer: parentIsContainer,
|
|
18
|
+
} = props;
|
|
13
19
|
classNames = buildStyleClassNamesFromData(data.styles);
|
|
14
20
|
|
|
15
21
|
classNames = buildStyleClassNamesExtenders({
|
|
@@ -24,14 +30,16 @@ const StyleWrapper = (props) => {
|
|
|
24
30
|
'',
|
|
25
31
|
// If we are rendering blocks inside a container, then pass also the data from the container
|
|
26
32
|
// This is needed in order to calculate properly the styles for the blocks inside the container
|
|
27
|
-
|
|
33
|
+
parentIsContainer && content.blocks ? content : {},
|
|
28
34
|
);
|
|
29
35
|
|
|
30
36
|
const rewrittenChildren = React.Children.map(children, (child) => {
|
|
31
37
|
if (React.isValidElement(child)) {
|
|
32
38
|
const childProps = {
|
|
33
39
|
...props,
|
|
34
|
-
className: cx([child.props.className, ...classNames]
|
|
40
|
+
className: cx([child.props.className, ...classNames], {
|
|
41
|
+
contained: parentIsContainer,
|
|
42
|
+
}),
|
|
35
43
|
style: { ...child.props.style, ...style },
|
|
36
44
|
};
|
|
37
45
|
return React.cloneElement(child, childProps);
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { defineConfig } from 'vitest/config';
|
|
2
2
|
import react from '@vitejs/plugin-react';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { svgLoader } from './vite-plugins/svg.
|
|
4
|
+
import { svgLoader } from './vite-plugins/svg.mjs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { createRequire } from 'module';
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
|
|
13
|
+
const projectRoot = path.resolve(__dirname);
|
|
5
14
|
|
|
6
15
|
export default defineConfig({
|
|
7
16
|
plugins: [
|
|
@@ -10,12 +19,19 @@ export default defineConfig({
|
|
|
10
19
|
svgoConfig: {
|
|
11
20
|
plugins: [
|
|
12
21
|
{
|
|
13
|
-
name: '
|
|
14
|
-
|
|
22
|
+
name: 'preset-default',
|
|
23
|
+
params: {
|
|
24
|
+
overrides: {
|
|
25
|
+
convertPathData: false,
|
|
26
|
+
removeViewBox: false,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
15
29
|
},
|
|
30
|
+
'removeTitle',
|
|
31
|
+
'removeUselessStrokeAndFill',
|
|
16
32
|
],
|
|
17
33
|
},
|
|
18
|
-
})
|
|
34
|
+
}),
|
|
19
35
|
],
|
|
20
36
|
resolve: {
|
|
21
37
|
alias: {
|
|
@@ -36,12 +52,12 @@ export default defineConfig({
|
|
|
36
52
|
globals: true,
|
|
37
53
|
environment: 'jsdom',
|
|
38
54
|
setupFiles: [
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
55
|
+
`${projectRoot}/test-setup-globals-vitest.js`,
|
|
56
|
+
`${projectRoot}/test-setup-config.jsx`,
|
|
57
|
+
`${projectRoot}/jest-setup-afterenv.js`,
|
|
58
|
+
`${projectRoot}/jest-addons-loader.js`,
|
|
43
59
|
],
|
|
44
|
-
globalSetup:
|
|
60
|
+
globalSetup: `${projectRoot}/global-test-setup.js`,
|
|
45
61
|
coverage: {
|
|
46
62
|
provider: 'v8',
|
|
47
63
|
reporter: ['text', 'json', 'html'],
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Provider } from 'react-intl-redux';
|
|
3
|
-
import { render, waitFor } from '@testing-library/react';
|
|
4
|
-
import configureStore from 'redux-mock-store';
|
|
5
|
-
import FileWidget from './FileWidget';
|
|
6
|
-
|
|
7
|
-
vi.spyOn(global.Date, 'now').mockImplementation(() => 1234567890);
|
|
8
|
-
|
|
9
|
-
const mockStore = configureStore();
|
|
10
|
-
|
|
11
|
-
const createStore = () =>
|
|
12
|
-
mockStore({
|
|
13
|
-
intl: {
|
|
14
|
-
locale: 'en',
|
|
15
|
-
messages: {},
|
|
16
|
-
},
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
describe('FileWidget', () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
vi.clearAllTimers();
|
|
22
|
-
Object.defineProperty(global.Image.prototype, 'complete', {
|
|
23
|
-
get() {
|
|
24
|
-
return true;
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
afterEach(() => {
|
|
30
|
-
vi.clearAllMocks();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('renders an empty file widget component', async () => {
|
|
34
|
-
const store = createStore();
|
|
35
|
-
|
|
36
|
-
const { container } = render(
|
|
37
|
-
<Provider store={store}>
|
|
38
|
-
<FileWidget
|
|
39
|
-
id="my-field"
|
|
40
|
-
title="My field"
|
|
41
|
-
fieldSet="default"
|
|
42
|
-
onChange={() => {}}
|
|
43
|
-
/>
|
|
44
|
-
</Provider>,
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
await waitFor(
|
|
48
|
-
() => {
|
|
49
|
-
expect(container.querySelector('.file-widget-dropzone')).toBeTruthy();
|
|
50
|
-
},
|
|
51
|
-
{ timeout: 1000 },
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
expect(container).toMatchSnapshot();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('renders a file widget component with value', async () => {
|
|
58
|
-
const store = createStore();
|
|
59
|
-
|
|
60
|
-
const { container } = render(
|
|
61
|
-
<Provider store={store}>
|
|
62
|
-
<FileWidget
|
|
63
|
-
id="my-field"
|
|
64
|
-
title="My field"
|
|
65
|
-
fieldSet="default"
|
|
66
|
-
onChange={() => {}}
|
|
67
|
-
value={{
|
|
68
|
-
download: 'http://myfile',
|
|
69
|
-
'content-type': 'image/png',
|
|
70
|
-
filename: 'myfile',
|
|
71
|
-
encoding: '',
|
|
72
|
-
}}
|
|
73
|
-
/>
|
|
74
|
-
</Provider>,
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
await waitFor(
|
|
78
|
-
() => {
|
|
79
|
-
const dropzone = container.querySelector('.file-widget-dropzone');
|
|
80
|
-
const preview = container.querySelector('.image-preview');
|
|
81
|
-
const filename = container.querySelector('.field-file-name');
|
|
82
|
-
|
|
83
|
-
return dropzone && preview && filename;
|
|
84
|
-
},
|
|
85
|
-
{ timeout: 1000 },
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
expect(container).toMatchSnapshot();
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
test('renders a file widget component with value in raw data', async () => {
|
|
92
|
-
const store = createStore();
|
|
93
|
-
|
|
94
|
-
const { container } = render(
|
|
95
|
-
<Provider store={store}>
|
|
96
|
-
<FileWidget
|
|
97
|
-
id="my-field"
|
|
98
|
-
title="My field"
|
|
99
|
-
fieldSet="default"
|
|
100
|
-
onChange={() => {}}
|
|
101
|
-
value={{
|
|
102
|
-
data: 'oiweurtksdgfjaslfqw9523563456',
|
|
103
|
-
'content-type': 'image/png',
|
|
104
|
-
filename: 'myfile',
|
|
105
|
-
encoding: 'base64',
|
|
106
|
-
}}
|
|
107
|
-
/>
|
|
108
|
-
</Provider>,
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
await waitFor(
|
|
112
|
-
() => {
|
|
113
|
-
const dropzone = container.querySelector('.file-widget-dropzone');
|
|
114
|
-
const filename = container.querySelector('.field-file-name');
|
|
115
|
-
|
|
116
|
-
return dropzone && filename;
|
|
117
|
-
},
|
|
118
|
-
{ timeout: 1000 },
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
expect(container).toMatchSnapshot();
|
|
122
|
-
});
|
|
123
|
-
});
|