@eeacms/volto-tabs-block 6.0.2 → 7.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.
- package/CHANGELOG.md +84 -21
- package/README.md +18 -1
- package/locales/de/LC_MESSAGES/volto.po +76 -29
- package/locales/en/LC_MESSAGES/volto.po +76 -29
- package/locales/es/LC_MESSAGES/volto.po +77 -30
- package/locales/it/LC_MESSAGES/volto.po +76 -29
- package/locales/pt_BR/LC_MESSAGES/volto.po +77 -30
- package/locales/ro/LC_MESSAGES/volto.po +76 -29
- package/locales/volto.pot +77 -30
- package/package.json +1 -1
- package/src/components/Edit.jsx +119 -102
- package/src/components/View.jsx +6 -4
- package/src/components/index.js +1 -0
- package/src/components/layoutSchema.js +3 -1
- package/src/components/schema.js +169 -70
- package/src/components/templates/accordion/Edit.jsx +28 -199
- package/src/components/templates/accordion/View.jsx +42 -64
- package/src/components/templates/accordion/index.js +1 -2
- package/src/components/templates/accordion/schema.js +33 -40
- package/src/components/templates/carousel/HorizontalView.jsx +3 -0
- package/src/components/templates/carousel/VerticalView.jsx +3 -0
- package/src/components/templates/carousel/index.js +1 -2
- package/src/components/templates/carousel/schema.js +19 -25
- package/src/components/templates/default/Edit.jsx +90 -50
- package/src/components/templates/default/View.jsx +112 -43
- package/src/components/templates/default/index.js +2 -2
- package/src/components/templates/default/schema.js +69 -77
- package/src/components/templates/horizontal-responsive/Edit.jsx +63 -46
- package/src/components/templates/horizontal-responsive/View.jsx +33 -37
- package/src/components/templates/horizontal-responsive/index.js +1 -6
- package/src/components/templates/horizontal-responsive/schema.js +6 -5
- package/src/helpers.js +14 -10
- package/src/helpers.test.js +14 -8
- package/src/index.js +34 -22
- package/src/less/carousel.less +9 -0
- package/src/less/edit.less +26 -0
- package/src/less/menu.less +118 -4
- package/src/less/menu.variables +16 -0
- package/src/less/tabs.less +53 -23
- package/src/less/tabs.variables +3 -0
- package/src/widgets/TabsWidget.jsx +158 -68
|
@@ -5,10 +5,25 @@ import move from 'lodash-move';
|
|
|
5
5
|
import { Icon, FormFieldWrapper, DragDropList } from '@plone/volto/components';
|
|
6
6
|
import { emptyTab } from '@eeacms/volto-tabs-block/helpers';
|
|
7
7
|
import { StyleWrapperEdit } from '@eeacms/volto-block-style/StyleWrapper';
|
|
8
|
+
import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
|
|
9
|
+
import { Accordion, Button, Segment } from 'semantic-ui-react';
|
|
10
|
+
import { useIntl } from 'react-intl';
|
|
11
|
+
|
|
8
12
|
import dragSVG from '@plone/volto/icons/drag.svg';
|
|
9
13
|
import themeSVG from '@plone/volto/icons/theme.svg';
|
|
10
14
|
import trashSVG from '@plone/volto/icons/delete.svg';
|
|
11
|
-
import plusSVG from '@plone/volto/icons/
|
|
15
|
+
import plusSVG from '@plone/volto/icons/add.svg';
|
|
16
|
+
import upSVG from '@plone/volto/icons/up-key.svg';
|
|
17
|
+
import downSVG from '@plone/volto/icons/down-key.svg';
|
|
18
|
+
|
|
19
|
+
import { defineMessages } from 'react-intl';
|
|
20
|
+
|
|
21
|
+
const messages = defineMessages({
|
|
22
|
+
AddTab: {
|
|
23
|
+
defaultMessage: 'Add Tab',
|
|
24
|
+
id: 'addTab',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
12
27
|
|
|
13
28
|
export function moveColumn(formData, source, destination) {
|
|
14
29
|
return {
|
|
@@ -19,14 +34,20 @@ export function moveColumn(formData, source, destination) {
|
|
|
19
34
|
};
|
|
20
35
|
}
|
|
21
36
|
|
|
22
|
-
const empty = () => {
|
|
23
|
-
return [
|
|
37
|
+
const empty = ({ schema, intl }) => {
|
|
38
|
+
return [
|
|
39
|
+
uuid(),
|
|
40
|
+
emptyTab({
|
|
41
|
+
schema,
|
|
42
|
+
intl,
|
|
43
|
+
}),
|
|
44
|
+
];
|
|
24
45
|
};
|
|
25
46
|
|
|
26
47
|
const TabsWidget = (props) => {
|
|
27
48
|
const [blockStyleVisible, setBlockStyleVisible] = React.useState(false);
|
|
28
49
|
const [activeTabId, setActiveTabId] = React.useState(0);
|
|
29
|
-
const { value = {}, id, onChange } = props;
|
|
50
|
+
const { value = {}, id, onChange, schema, schemaExtender } = props;
|
|
30
51
|
const { blocks = {} } = value;
|
|
31
52
|
const tabsList = (value.blocks_layout?.items || []).map((uid) => [
|
|
32
53
|
uid,
|
|
@@ -34,12 +55,63 @@ const TabsWidget = (props) => {
|
|
|
34
55
|
]);
|
|
35
56
|
const activeTabData = blocks[activeTabId] || {};
|
|
36
57
|
|
|
58
|
+
const [localActiveObject, setLocalActiveObject] = React.useState(
|
|
59
|
+
props.activeObject ?? value.length - 1,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
let activeObject, setActiveObject;
|
|
63
|
+
if (
|
|
64
|
+
(props.activeObject || props.activeObject === 0) &&
|
|
65
|
+
props.setActiveObject
|
|
66
|
+
) {
|
|
67
|
+
activeObject = props.activeObject;
|
|
68
|
+
setActiveObject = props.setActiveObject;
|
|
69
|
+
} else {
|
|
70
|
+
activeObject = localActiveObject;
|
|
71
|
+
setActiveObject = setLocalActiveObject;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function handleChangeActiveObject(e, blockProps) {
|
|
75
|
+
const { index } = blockProps;
|
|
76
|
+
const newIndex = activeObject === index ? -1 : index;
|
|
77
|
+
|
|
78
|
+
setActiveObject(newIndex);
|
|
79
|
+
}
|
|
80
|
+
const intl = useIntl();
|
|
81
|
+
const objectSchema = typeof schema === 'function' ? schema(props) : schema;
|
|
82
|
+
|
|
37
83
|
return (
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
84
|
+
<div className="objectlist-widget">
|
|
85
|
+
<FormFieldWrapper
|
|
86
|
+
{...props}
|
|
87
|
+
// draggable={false}
|
|
88
|
+
className="drag-drop-list-widget"
|
|
89
|
+
>
|
|
90
|
+
<div className="add-item-button-wrapper">
|
|
91
|
+
<Button
|
|
92
|
+
compact
|
|
93
|
+
icon
|
|
94
|
+
onClick={() => {
|
|
95
|
+
const [newId, newData] = empty({ schema: objectSchema, intl });
|
|
96
|
+
onChange(id, {
|
|
97
|
+
...value,
|
|
98
|
+
blocks: {
|
|
99
|
+
...value.blocks,
|
|
100
|
+
[newId]: newData,
|
|
101
|
+
},
|
|
102
|
+
blocks_layout: {
|
|
103
|
+
...value.blocks_layout,
|
|
104
|
+
items: [...value.blocks_layout?.items, newId],
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
<Icon name={plusSVG} size="18px" />
|
|
110
|
+
{intl.formatMessage(messages.AddTab)}
|
|
111
|
+
</Button>
|
|
112
|
+
</div>
|
|
113
|
+
</FormFieldWrapper>
|
|
114
|
+
|
|
43
115
|
<div className="tabs-area">
|
|
44
116
|
<DragDropList
|
|
45
117
|
childList={tabsList}
|
|
@@ -61,78 +133,96 @@ const TabsWidget = (props) => {
|
|
|
61
133
|
const { childId, child, index, draginfo } = dragProps;
|
|
62
134
|
return (
|
|
63
135
|
<div ref={draginfo.innerRef} {...draginfo.draggableProps}>
|
|
64
|
-
<
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}}
|
|
70
|
-
{...draginfo.dragHandleProps}
|
|
71
|
-
className="drag handle wrapper"
|
|
136
|
+
<Accordion key={index} fluid styled>
|
|
137
|
+
<Accordion.Title
|
|
138
|
+
active={activeObject === index}
|
|
139
|
+
index={index}
|
|
140
|
+
onClick={handleChangeActiveObject}
|
|
72
141
|
>
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
{child.title || `Tab ${index + 1}`}
|
|
78
|
-
</div>
|
|
79
|
-
<button
|
|
80
|
-
onClick={() => {
|
|
81
|
-
setActiveTabId(childId);
|
|
82
|
-
setBlockStyleVisible(true);
|
|
142
|
+
<div
|
|
143
|
+
style={{
|
|
144
|
+
visibility: 'visible',
|
|
145
|
+
display: 'inline-block',
|
|
83
146
|
}}
|
|
84
|
-
|
|
147
|
+
{...draginfo.dragHandleProps}
|
|
148
|
+
className="drag handle"
|
|
85
149
|
>
|
|
86
|
-
<Icon name={
|
|
87
|
-
</
|
|
88
|
-
|
|
150
|
+
<Icon name={dragSVG} size="18px" />
|
|
151
|
+
</div>
|
|
152
|
+
<div className="label">{`Tab #${index + 1}`}</div>
|
|
153
|
+
|
|
154
|
+
<div className="accordion-tools">
|
|
89
155
|
<button
|
|
90
156
|
onClick={() => {
|
|
91
|
-
|
|
157
|
+
setActiveTabId(childId);
|
|
158
|
+
setBlockStyleVisible(true);
|
|
159
|
+
}}
|
|
160
|
+
title="Apply style"
|
|
161
|
+
>
|
|
162
|
+
<Icon name={themeSVG} size="20px" />
|
|
163
|
+
</button>
|
|
164
|
+
{value.blocks_layout?.items?.length > 1 ? (
|
|
165
|
+
<button
|
|
166
|
+
onClick={() => {
|
|
167
|
+
const newFormData = {
|
|
168
|
+
...value,
|
|
169
|
+
blocks: omit({ ...value.blocks }, [childId]),
|
|
170
|
+
blocks_layout: {
|
|
171
|
+
...value.blocks_layout,
|
|
172
|
+
items: without(
|
|
173
|
+
[...value.blocks_layout?.items],
|
|
174
|
+
childId,
|
|
175
|
+
),
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
onChange(id, newFormData);
|
|
179
|
+
}}
|
|
180
|
+
title="Delete tab"
|
|
181
|
+
>
|
|
182
|
+
<Icon name={trashSVG} size="20px" color="#e40166" />
|
|
183
|
+
</button>
|
|
184
|
+
) : (
|
|
185
|
+
''
|
|
186
|
+
)}
|
|
187
|
+
{activeObject === index ? (
|
|
188
|
+
<Icon name={upSVG} size="20px" />
|
|
189
|
+
) : (
|
|
190
|
+
<Icon name={downSVG} size="20px" />
|
|
191
|
+
)}
|
|
192
|
+
</div>
|
|
193
|
+
</Accordion.Title>
|
|
194
|
+
<Accordion.Content active={activeObject === index}>
|
|
195
|
+
<Segment>
|
|
196
|
+
<ObjectWidget
|
|
197
|
+
id={`${id}-${index}`}
|
|
198
|
+
key={`ow-${id}-${index}`}
|
|
199
|
+
block={props.block}
|
|
200
|
+
schema={
|
|
201
|
+
schemaExtender
|
|
202
|
+
? schemaExtender(schema, child, intl)
|
|
203
|
+
: objectSchema
|
|
204
|
+
}
|
|
205
|
+
value={child}
|
|
206
|
+
onChange={(fi, fv) => {
|
|
207
|
+
onChange(id, {
|
|
92
208
|
...value,
|
|
93
|
-
blocks:
|
|
209
|
+
blocks: {
|
|
210
|
+
...value.blocks,
|
|
211
|
+
[childId]: fv,
|
|
212
|
+
},
|
|
94
213
|
blocks_layout: {
|
|
95
214
|
...value.blocks_layout,
|
|
96
|
-
items: without(
|
|
97
|
-
[...value.blocks_layout?.items],
|
|
98
|
-
childId,
|
|
99
|
-
),
|
|
100
215
|
},
|
|
101
|
-
};
|
|
102
|
-
onChange(id, newFormData);
|
|
216
|
+
});
|
|
103
217
|
}}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
) : (
|
|
109
|
-
''
|
|
110
|
-
)}
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
218
|
+
/>
|
|
219
|
+
</Segment>
|
|
220
|
+
</Accordion.Content>
|
|
221
|
+
</Accordion>
|
|
113
222
|
</div>
|
|
114
223
|
);
|
|
115
224
|
}}
|
|
116
225
|
</DragDropList>
|
|
117
|
-
<button
|
|
118
|
-
onClick={() => {
|
|
119
|
-
const [newId, newData] = empty();
|
|
120
|
-
onChange(id, {
|
|
121
|
-
...value,
|
|
122
|
-
blocks: {
|
|
123
|
-
...value.blocks,
|
|
124
|
-
[newId]: newData,
|
|
125
|
-
},
|
|
126
|
-
blocks_layout: {
|
|
127
|
-
...value.blocks_layout,
|
|
128
|
-
items: [...value.blocks_layout?.items, newId],
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
}}
|
|
132
|
-
title="Add new tab"
|
|
133
|
-
>
|
|
134
|
-
<Icon name={plusSVG} size="18px" />
|
|
135
|
-
</button>
|
|
136
226
|
</div>
|
|
137
227
|
<StyleWrapperEdit
|
|
138
228
|
{...props}
|
|
@@ -167,7 +257,7 @@ const TabsWidget = (props) => {
|
|
|
167
257
|
})
|
|
168
258
|
}
|
|
169
259
|
/>
|
|
170
|
-
</
|
|
260
|
+
</div>
|
|
171
261
|
);
|
|
172
262
|
};
|
|
173
263
|
|