@plone/volto 17.8.0 → 17.10.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 +24 -0
- package/package.json +5 -5
- package/packages/volto-slate/package.json +1 -1
- package/src/components/manage/Widgets/ColorPickerWidget.stories.tsx +48 -0
- package/src/components/manage/Widgets/{ColorPickerWidget.jsx → ColorPickerWidget.tsx} +40 -23
- package/src/helpers/Blocks/Blocks.js +10 -2
- package/src/helpers/Blocks/Blocks.test.js +20 -0
- package/src/components/manage/Widgets/ColorPickerWidget.stories.jsx +0 -30
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,30 @@ myst:
|
|
|
17
17
|
|
|
18
18
|
<!-- towncrier release notes start -->
|
|
19
19
|
|
|
20
|
+
## 17.10.0 (2024-01-11)
|
|
21
|
+
|
|
22
|
+
### Feature
|
|
23
|
+
|
|
24
|
+
- Enhanced `ColorPickerWidget` with additional color definitions, saving it as an object instead of a string. @sneridagh [#5585](https://github.com/plone/volto/issues/5585)
|
|
25
|
+
|
|
26
|
+
### Internal
|
|
27
|
+
|
|
28
|
+
- Update to latest @plone/scripts @sneridagh [#5612](https://github.com/plone/volto/issues/5612)
|
|
29
|
+
|
|
30
|
+
## 17.9.0 (2024-01-04)
|
|
31
|
+
|
|
32
|
+
### Feature
|
|
33
|
+
|
|
34
|
+
- Allow to opt out of the nested prefixed name build in the custom CSS properties style name generator if an object is found in the style wrapper object. @sneridagh [#5586](https://github.com/plone/volto/issues/5586)
|
|
35
|
+
|
|
36
|
+
### Bugfix
|
|
37
|
+
|
|
38
|
+
- Refactoring the code for extraction of videoDetails from the video URL, adding code for extracting videoDetails from youtube video URLs with '/live/' in its URL which previously used to throw an error and adding jest tests for same. @IshaanDasgupta [#5416](https://github.com/plone/volto/issues/5416)
|
|
39
|
+
|
|
40
|
+
### Internal
|
|
41
|
+
|
|
42
|
+
- Pin mrs-developer to latest version, not to star @sneridagh [#5593](https://github.com/plone/volto/issues/5593)
|
|
43
|
+
|
|
20
44
|
## 17.8.0 (2024-01-02)
|
|
21
45
|
|
|
22
46
|
### Feature
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
}
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"version": "17.
|
|
12
|
+
"version": "17.10.0",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
15
|
"url": "git@github.com:plone/volto.git"
|
|
@@ -186,13 +186,13 @@
|
|
|
186
186
|
"release-it": {
|
|
187
187
|
"hooks": {
|
|
188
188
|
"before:bump": [
|
|
189
|
-
"yarn i18n"
|
|
189
|
+
"yarn i18n",
|
|
190
|
+
"yarn build:types"
|
|
190
191
|
],
|
|
191
192
|
"after:bump": [
|
|
192
193
|
"pipx run towncrier build --draft --yes --version ${version} > .changelog.draft && pipx run towncrier build --yes --version ${version}",
|
|
193
194
|
"make corepackagebump VERSION=${version}",
|
|
194
|
-
"make copyreleasenotestodocs"
|
|
195
|
-
"yarn build:types"
|
|
195
|
+
"make copyreleasenotestodocs"
|
|
196
196
|
],
|
|
197
197
|
"after:release": "rm .changelog.draft"
|
|
198
198
|
},
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
"@loadable/component": "5.14.1",
|
|
248
248
|
"@loadable/server": "5.14.0",
|
|
249
249
|
"@loadable/webpack-plugin": "5.15.2",
|
|
250
|
-
"@plone/scripts": "3.
|
|
250
|
+
"@plone/scripts": "^3.2.1",
|
|
251
251
|
"@testing-library/cypress": "9.0.0",
|
|
252
252
|
"@testing-library/jest-dom": "5.16.4",
|
|
253
253
|
"@testing-library/react": "12.1.5",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import ColorPickerWidget from './ColorPickerWidget';
|
|
2
|
+
import WidgetStory from './story';
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof ColorPickerWidget> = {
|
|
6
|
+
title: 'Edit Widgets/ColorPicker',
|
|
7
|
+
component: WidgetStory.bind({
|
|
8
|
+
widget: ColorPickerWidget,
|
|
9
|
+
}),
|
|
10
|
+
decorators: [
|
|
11
|
+
(Story) => (
|
|
12
|
+
<div className="ui segment form attached" style={{ width: '400px' }}>
|
|
13
|
+
<Story />
|
|
14
|
+
</div>
|
|
15
|
+
),
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default meta;
|
|
20
|
+
type Story = StoryObj<typeof ColorPickerWidget>;
|
|
21
|
+
|
|
22
|
+
export const Default: Story = {
|
|
23
|
+
args: {
|
|
24
|
+
id: 'favoriteColor',
|
|
25
|
+
title: 'Favorite Color',
|
|
26
|
+
colors: [
|
|
27
|
+
{ name: 'red', label: 'red' },
|
|
28
|
+
{ name: 'yellow', label: 'yellow' },
|
|
29
|
+
{ name: 'green', label: 'green' },
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const WithEnhancedStyleConfig: Story = {
|
|
35
|
+
args: {
|
|
36
|
+
id: 'favoriteColor',
|
|
37
|
+
title: 'Favorite Color',
|
|
38
|
+
colors: [
|
|
39
|
+
{ name: 'red', label: 'red', style: { '--background-color': 'red' } },
|
|
40
|
+
{
|
|
41
|
+
name: 'yellow',
|
|
42
|
+
label: 'yellow',
|
|
43
|
+
style: { '--background-color': 'yellow' },
|
|
44
|
+
},
|
|
45
|
+
{ name: 'green', label: 'green' },
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
2
|
import { Form } from 'semantic-ui-react';
|
|
4
3
|
import { Grid, Button } from 'semantic-ui-react';
|
|
4
|
+
import { isEqual } from 'lodash';
|
|
5
5
|
import { defineMessages, useIntl } from 'react-intl';
|
|
6
6
|
|
|
7
7
|
const messages = defineMessages({
|
|
@@ -11,7 +11,31 @@ const messages = defineMessages({
|
|
|
11
11
|
},
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
type Color =
|
|
15
|
+
| {
|
|
16
|
+
name: string;
|
|
17
|
+
label: string;
|
|
18
|
+
style: Record<`--${string}`, string>;
|
|
19
|
+
}
|
|
20
|
+
| {
|
|
21
|
+
name: string;
|
|
22
|
+
label: string;
|
|
23
|
+
style: undefined;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type ColorPickerWidgetProps = {
|
|
27
|
+
id: string;
|
|
28
|
+
title: string;
|
|
29
|
+
value: string;
|
|
30
|
+
default: string;
|
|
31
|
+
required: boolean;
|
|
32
|
+
missing_value: unknown;
|
|
33
|
+
className: string;
|
|
34
|
+
onChange: (id: string, value: any) => void;
|
|
35
|
+
colors: Color[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const ColorPickerWidget = (props: ColorPickerWidgetProps) => {
|
|
15
39
|
const { id, title, required, value, onChange, colors, className } = props;
|
|
16
40
|
|
|
17
41
|
const intl = useIntl();
|
|
@@ -30,6 +54,7 @@ const ColorPickerWidget = (props) => {
|
|
|
30
54
|
className={className}
|
|
31
55
|
id={'field-' + id}
|
|
32
56
|
>
|
|
57
|
+
{/* @ts-ignore */}
|
|
33
58
|
<Grid>
|
|
34
59
|
<Grid.Row>
|
|
35
60
|
<Grid.Column
|
|
@@ -44,21 +69,29 @@ const ColorPickerWidget = (props) => {
|
|
|
44
69
|
|
|
45
70
|
<div className="buttons">
|
|
46
71
|
{colors.map((color) => {
|
|
72
|
+
let colorValue: string | Color['style'];
|
|
73
|
+
const colorName = color.name;
|
|
74
|
+
if (color.style !== undefined) {
|
|
75
|
+
colorValue = color.style;
|
|
76
|
+
} else {
|
|
77
|
+
colorValue = color.name;
|
|
78
|
+
}
|
|
47
79
|
return (
|
|
48
80
|
<Button
|
|
49
|
-
key={id +
|
|
50
|
-
className={
|
|
81
|
+
key={id + colorName}
|
|
82
|
+
className={colorName}
|
|
51
83
|
onClick={(e) => {
|
|
52
84
|
e.preventDefault();
|
|
53
85
|
e.stopPropagation();
|
|
54
86
|
onChange(
|
|
55
87
|
id,
|
|
56
|
-
value ===
|
|
88
|
+
value === colorValue
|
|
57
89
|
? props.missing_value
|
|
58
|
-
:
|
|
90
|
+
: colorValue,
|
|
59
91
|
);
|
|
60
92
|
}}
|
|
61
|
-
|
|
93
|
+
style={color.style}
|
|
94
|
+
active={isEqual(value, colorValue)}
|
|
62
95
|
circular
|
|
63
96
|
aria-label={color.label}
|
|
64
97
|
title={color.label}
|
|
@@ -74,20 +107,4 @@ const ColorPickerWidget = (props) => {
|
|
|
74
107
|
) : null;
|
|
75
108
|
};
|
|
76
109
|
|
|
77
|
-
ColorPickerWidget.propTypes = {
|
|
78
|
-
id: PropTypes.string.isRequired,
|
|
79
|
-
title: PropTypes.string.isRequired,
|
|
80
|
-
required: PropTypes.bool,
|
|
81
|
-
value: PropTypes.string,
|
|
82
|
-
onChange: PropTypes.func,
|
|
83
|
-
colors: PropTypes.array,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
ColorPickerWidget.defaultProps = {
|
|
87
|
-
required: false,
|
|
88
|
-
value: null,
|
|
89
|
-
onChange: null,
|
|
90
|
-
colors: [],
|
|
91
|
-
};
|
|
92
|
-
|
|
93
110
|
export default ColorPickerWidget;
|
|
@@ -642,13 +642,21 @@ export const buildStyleObjectFromData = (obj = {}, prefix = '') => {
|
|
|
642
642
|
// ...(() => {
|
|
643
643
|
// if (isObject(v)) {
|
|
644
644
|
// return Object.entries(
|
|
645
|
-
// buildStyleObjectFromData(
|
|
645
|
+
// buildStyleObjectFromData(
|
|
646
|
+
// v,
|
|
647
|
+
// `${k.endsWith(':noprefix') ? '' : `${prefix}${k}--`}`,
|
|
648
|
+
// ),
|
|
646
649
|
// );
|
|
647
650
|
// }
|
|
648
651
|
// return [styleDataToStyleObject(k, v, prefix)];
|
|
649
652
|
// })(),
|
|
650
653
|
...(isObject(v)
|
|
651
|
-
? Object.entries(
|
|
654
|
+
? Object.entries(
|
|
655
|
+
buildStyleObjectFromData(
|
|
656
|
+
v,
|
|
657
|
+
`${k.endsWith(':noprefix') ? '' : `${prefix}${k}--`}`, // We don't add a prefix if the key ends with the marker suffix
|
|
658
|
+
),
|
|
659
|
+
)
|
|
652
660
|
: [styleDataToStyleObject(k, v, prefix)]),
|
|
653
661
|
],
|
|
654
662
|
[],
|
|
@@ -1123,6 +1123,26 @@ describe('Blocks', () => {
|
|
|
1123
1123
|
'--nested--level2--foo': '#fff',
|
|
1124
1124
|
});
|
|
1125
1125
|
});
|
|
1126
|
+
|
|
1127
|
+
it('Supports multiple nested levels and optional inclusion of the name of the level', () => {
|
|
1128
|
+
const styles = {
|
|
1129
|
+
'--color': 'red',
|
|
1130
|
+
backgroundColor: '#AABBCC',
|
|
1131
|
+
'nested:noprefix': {
|
|
1132
|
+
l1: 'white',
|
|
1133
|
+
'--foo': 'white',
|
|
1134
|
+
level2: {
|
|
1135
|
+
'--foo': '#fff',
|
|
1136
|
+
bar: '#000',
|
|
1137
|
+
},
|
|
1138
|
+
},
|
|
1139
|
+
};
|
|
1140
|
+
expect(buildStyleObjectFromData(styles)).toEqual({
|
|
1141
|
+
'--color': 'red',
|
|
1142
|
+
'--foo': 'white',
|
|
1143
|
+
'--level2--foo': '#fff',
|
|
1144
|
+
});
|
|
1145
|
+
});
|
|
1126
1146
|
});
|
|
1127
1147
|
|
|
1128
1148
|
describe('getPreviousNextBlock', () => {
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import ColorPickerWidget from './ColorPickerWidget';
|
|
3
|
-
import WidgetStory from './story';
|
|
4
|
-
|
|
5
|
-
export const Default = WidgetStory.bind({
|
|
6
|
-
widget: ColorPickerWidget,
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
Default.args = {
|
|
10
|
-
id: 'favoriteColor',
|
|
11
|
-
title: 'Favorite Color',
|
|
12
|
-
colors: [
|
|
13
|
-
{ name: 'red', label: 'red' },
|
|
14
|
-
{ name: 'yellow', label: 'yellow' },
|
|
15
|
-
{ name: 'green', label: 'green' },
|
|
16
|
-
],
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
title: 'Edit Widgets/ColorPicker',
|
|
21
|
-
component: Default,
|
|
22
|
-
decorators: [
|
|
23
|
-
(Story) => (
|
|
24
|
-
<div className="ui segment form attached" style={{ width: '400px' }}>
|
|
25
|
-
<Story />
|
|
26
|
-
</div>
|
|
27
|
-
),
|
|
28
|
-
],
|
|
29
|
-
argTypes: {},
|
|
30
|
-
};
|