@eeacms/volto-tabs-block 5.0.1 → 5.0.3
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 +45 -2
- package/jest-addon.config.js +2 -2
- package/package.json +2 -2
- package/src/components/Edit.jsx +4 -2
- package/src/components/schema.js +0 -1
- package/src/components/templates/accordion/Edit.jsx +374 -10
- package/src/components/templates/accordion/View.jsx +17 -10
- package/src/components/templates/carousel/HorizontalView.jsx +1 -1
- package/src/components/templates/default/View.jsx +12 -4
- package/src/components/templates/horizontal-responsive/Edit.jsx +446 -0
- package/src/components/templates/horizontal-responsive/View.jsx +12 -3
- package/src/components/templates/horizontal-responsive/index.js +6 -2
- package/src/index.js +2 -1
- package/src/less/menu.less +91 -4
- package/src/less/tabs.less +48 -3
- package/src/utils/dimensions.js +0 -1
- package/src/utils/index.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,54 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
-
### [5.0.
|
|
7
|
+
### [5.0.3](https://github.com/eea/volto-tabs-block/compare/5.0.2...5.0.3) - 12 June 2023
|
|
8
|
+
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- chore: [JENKINS] Deprecate circularity website [valentinab25 - [`820aaa9`](https://github.com/eea/volto-tabs-block/commit/820aaa963e978a893a23b77f694bb011f3d768c1)]
|
|
12
|
+
|
|
13
|
+
#### :hammer_and_wrench: Others
|
|
14
|
+
|
|
15
|
+
- test: jest should look for addons in node_modules Refs #253277 [valentinab25 - [`e3b0519`](https://github.com/eea/volto-tabs-block/commit/e3b051969a3dac74b5f33340447fe98ffbc0fb14)]
|
|
16
|
+
- test: Fix test config, coverage Refs #253277 [valentinab25 - [`82d25a1`](https://github.com/eea/volto-tabs-block/commit/82d25a1bdc0106a95b39ee55e4b3f34fee89bd9a)]
|
|
17
|
+
### [5.0.2](https://github.com/eea/volto-tabs-block/compare/5.0.1...5.0.2) - 19 May 2023
|
|
8
18
|
|
|
9
19
|
#### :bug: Bug Fixes
|
|
10
20
|
|
|
11
|
-
- fix:
|
|
21
|
+
- fix: git lint not ok #252540 [Andrei Grigore - [`8f6aaf9`](https://github.com/eea/volto-tabs-block/commit/8f6aaf9dcda00a60a70fb28012e95cf9dfe201c9)]
|
|
22
|
+
|
|
23
|
+
#### :hammer_and_wrench: Others
|
|
24
|
+
|
|
25
|
+
- same name consistency [Andrei Grigore - [`2dd0742`](https://github.com/eea/volto-tabs-block/commit/2dd074241ef0a44c4a9dd8d2aa49dde50ddc6a9c)]
|
|
26
|
+
- lint [Dobricean Ioan Dorian - [`85bb068`](https://github.com/eea/volto-tabs-block/commit/85bb06857cba1897960bdcdb68d8d1e4a9adfe88)]
|
|
27
|
+
- lint [Dobricean Ioan Dorian - [`5d3d44a`](https://github.com/eea/volto-tabs-block/commit/5d3d44a9c6bcf276ae15c9e6f1efbf0a9773cfc2)]
|
|
28
|
+
- lint [Dobricean Ioan Dorian - [`2086359`](https://github.com/eea/volto-tabs-block/commit/2086359d07f1aa95f6cc72fa4ca1e9c5594976e0)]
|
|
29
|
+
- lint [Dobricean Ioan Dorian - [`9cb8474`](https://github.com/eea/volto-tabs-block/commit/9cb8474410b4d6dccf993cee41b15b93f133922a)]
|
|
30
|
+
- final [Dobricean Ioan Dorian - [`6b502c7`](https://github.com/eea/volto-tabs-block/commit/6b502c7ba551f8cbd2d5260892d5e42782c09b4e)]
|
|
31
|
+
- accordion ready [Dobricean Ioan Dorian - [`224f397`](https://github.com/eea/volto-tabs-block/commit/224f397cb63ee0c11042e58f6ee010ac2688c07e)]
|
|
32
|
+
- horizontal responsive edit [Dobricean Ioan Dorian - [`846f618`](https://github.com/eea/volto-tabs-block/commit/846f618fba54989a66498672b333c7695d653844)]
|
|
33
|
+
- horizontal [Dobricean Ioan Dorian - [`877e906`](https://github.com/eea/volto-tabs-block/commit/877e906ebd63cd75fa5be215f6893c06480553e7)]
|
|
34
|
+
- horizontal [Dobricean Ioan Dorian - [`9d8c0dc`](https://github.com/eea/volto-tabs-block/commit/9d8c0dc86e9d22e3300e6afc8f63b620f4e6f5c3)]
|
|
35
|
+
- horizontal [Dobricean Ioan Dorian - [`2ceb2d6`](https://github.com/eea/volto-tabs-block/commit/2ceb2d65f64000714b19e45cbbdcf6dc50e8b3c6)]
|
|
36
|
+
- resize handler [Dobricean Ioan Dorian - [`94d825e`](https://github.com/eea/volto-tabs-block/commit/94d825e433beb34e1556143a8757a1b4f60bdd32)]
|
|
37
|
+
- inverted & icon & style & reverse [Dobricean Ioan Dorian - [`9b703c6`](https://github.com/eea/volto-tabs-block/commit/9b703c6338a9663587718ccfb33ebe5dec02edcb)]
|
|
38
|
+
- inverted & icon & style & reverse [Dobricean Ioan Dorian - [`aa9706b`](https://github.com/eea/volto-tabs-block/commit/aa9706bf5410a05e1a25803fade6b82fd3a36b9d)]
|
|
39
|
+
- edit blocks [Dobricean Ioan Dorian - [`d4b8126`](https://github.com/eea/volto-tabs-block/commit/d4b8126db32401bccab651ddfa4d9fddecfb6feb)]
|
|
40
|
+
- accordion design [Dobricean Ioan Dorian - [`943a842`](https://github.com/eea/volto-tabs-block/commit/943a842e8876d59d0a2b2dd8b560bb1ce95648c9)]
|
|
41
|
+
- remove useeffect [Dobricean Ioan Dorian - [`461d325`](https://github.com/eea/volto-tabs-block/commit/461d3257ca1830f669bfe09df893960ae003f05b)]
|
|
42
|
+
- accordion [Dobricean Ioan Dorian - [`a9c4e85`](https://github.com/eea/volto-tabs-block/commit/a9c4e85c1b4e50802d08acc0546e23afd2cda893)]
|
|
43
|
+
- lint [Dobricean Ioan Dorian - [`f920a0e`](https://github.com/eea/volto-tabs-block/commit/f920a0ec9259b0ecb8c837499ac7553e1df7d1cc)]
|
|
44
|
+
- first [Dobricean Ioan Dorian - [`6c305aa`](https://github.com/eea/volto-tabs-block/commit/6c305aae657c801c6e5e97db5747af56611602f2)]
|
|
45
|
+
- remove data content jj [dobri1408 - [`2464dee`](https://github.com/eea/volto-tabs-block/commit/2464deeac06a0a30eeaf5b56494c7d3f2753bc06)]
|
|
46
|
+
- lint [Dobricean Ioan Dorian - [`44e74f7`](https://github.com/eea/volto-tabs-block/commit/44e74f76c058fd0b571f12574a8ea4eedf96c114)]
|
|
47
|
+
- lint [Dobricean Ioan Dorian - [`8901729`](https://github.com/eea/volto-tabs-block/commit/89017292fe1125de027b1e046a760d30c0ad20da)]
|
|
48
|
+
- lint [Dobricean Ioan Dorian - [`08d2b07`](https://github.com/eea/volto-tabs-block/commit/08d2b076d3d0d50cb9e7ad65af7698250562d1e5)]
|
|
49
|
+
- seo slides and printing styles for carousel [Dobricean Ioan Dorian - [`5ec312b`](https://github.com/eea/volto-tabs-block/commit/5ec312b9d63788b9879e1e5417c53c54a4008ef1)]
|
|
50
|
+
- remove big border [Dobricean Ioan Dorian - [`fff673d`](https://github.com/eea/volto-tabs-block/commit/fff673d3a8b2ebeef72959b863acf221d70aa002)]
|
|
51
|
+
- default & horizontal responsive [Dobricean Ioan Dorian - [`f2b3444`](https://github.com/eea/volto-tabs-block/commit/f2b34442dfc336ab84680cced293486d8fc8af21)]
|
|
52
|
+
- accordion template [Dobricean Ioan Dorian - [`5649125`](https://github.com/eea/volto-tabs-block/commit/5649125263b92850c92b4e6a491ab3663f85a465)]
|
|
53
|
+
- fix select [Dobricean Ioan Dorian - [`7628e86`](https://github.com/eea/volto-tabs-block/commit/7628e86e43b79186960b9b72df567da1affcfaa7)]
|
|
54
|
+
### [5.0.1](https://github.com/eea/volto-tabs-block/compare/5.0.0...5.0.1) - 16 May 2023
|
|
12
55
|
|
|
13
56
|
## [5.0.0](https://github.com/eea/volto-tabs-block/compare/4.0.1...5.0.0) - 24 April 2023
|
|
14
57
|
|
package/jest-addon.config.js
CHANGED
|
@@ -5,19 +5,19 @@ module.exports = {
|
|
|
5
5
|
'!src/**/*.d.ts',
|
|
6
6
|
],
|
|
7
7
|
moduleNameMapper: {
|
|
8
|
+
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
|
8
9
|
'@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
|
|
9
10
|
'@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
|
|
10
11
|
'@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
11
12
|
'@package/(.*)$': '<rootDir>/src/$1',
|
|
12
13
|
'@root/(.*)$': '<rootDir>/src/$1',
|
|
13
14
|
'@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
|
|
14
|
-
'@eeacms/(.*?)/(.*)$': '<rootDir>/
|
|
15
|
+
'@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
|
|
15
16
|
'@plone/volto-slate':
|
|
16
17
|
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
|
|
17
18
|
'~/(.*)$': '<rootDir>/src/$1',
|
|
18
19
|
'load-volto-addons':
|
|
19
20
|
'<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
|
|
20
|
-
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
|
21
21
|
},
|
|
22
22
|
transform: {
|
|
23
23
|
'^.+\\.js(x)?$': 'babel-jest',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-tabs-block",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.3",
|
|
4
4
|
"description": "volto-tabs-block: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: IDM2 A-Team",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@eeacms/volto-anchors"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@eeacms/volto-block-style": "*",
|
|
25
24
|
"@eeacms/volto-anchors": "*",
|
|
25
|
+
"@eeacms/volto-block-style": "*",
|
|
26
26
|
"react-responsive-tabs": "4.4.3",
|
|
27
27
|
"react-slick": "^0.24.0",
|
|
28
28
|
"slick-carousel": "^1.8.1"
|
package/src/components/Edit.jsx
CHANGED
|
@@ -16,6 +16,7 @@ import '@eeacms/volto-tabs-block/less/edit.less';
|
|
|
16
16
|
import '@eeacms/volto-tabs-block/less/tabs.less';
|
|
17
17
|
|
|
18
18
|
const Edit = (props) => {
|
|
19
|
+
const view = React.useRef(null);
|
|
19
20
|
const { onChangeBlock, onChangeField } = props;
|
|
20
21
|
const { data = {}, block = null } = props;
|
|
21
22
|
const template = data.template || 'default';
|
|
@@ -150,11 +151,11 @@ const Edit = (props) => {
|
|
|
150
151
|
setActiveBlock(selected);
|
|
151
152
|
setMultiSelected(newMultiSelected);
|
|
152
153
|
};
|
|
153
|
-
|
|
154
154
|
return (
|
|
155
155
|
<BlockStyleWrapperEdit {...props}>
|
|
156
156
|
<div
|
|
157
|
-
className={cx('tabs-block edit', theme, verticalAlign)}
|
|
157
|
+
className={cx('tabs-block edit', theme, verticalAlign, template)}
|
|
158
|
+
ref={view}
|
|
158
159
|
role="presentation"
|
|
159
160
|
onKeyDown={(e) => {
|
|
160
161
|
handleKeyDown(e, props.index, props.block, props.blockNode.current);
|
|
@@ -183,6 +184,7 @@ const Edit = (props) => {
|
|
|
183
184
|
tabData={tabData}
|
|
184
185
|
tabsData={tabsData}
|
|
185
186
|
tabsList={tabsList}
|
|
187
|
+
node={view}
|
|
186
188
|
template={template}
|
|
187
189
|
onChangeTabData={onChangeTabData}
|
|
188
190
|
onSelectBlock={onSelectBlock}
|
package/src/components/schema.js
CHANGED
|
@@ -1,18 +1,382 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import { compose } from 'redux';
|
|
4
|
+
import { isEmpty } from 'lodash';
|
|
5
|
+
import { v4 as uuid } from 'uuid';
|
|
6
|
+
import { withRouter } from 'react-router';
|
|
7
|
+
import Tabs from 'react-responsive-tabs';
|
|
8
|
+
import AnimateHeight from 'react-animate-height';
|
|
9
|
+
import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
|
|
10
|
+
import { emptyBlocksForm } from '@plone/volto/helpers';
|
|
11
|
+
import { BlocksForm } from '@plone/volto/components';
|
|
12
|
+
import { Icon } from 'semantic-ui-react';
|
|
13
|
+
import { Menu, Input } from 'semantic-ui-react';
|
|
14
|
+
import { Icon as VoltoIcon } from '@plone/volto/components';
|
|
15
|
+
import config from '@plone/volto/registry';
|
|
16
|
+
import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
|
|
17
|
+
import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
|
|
18
|
+
import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
|
|
19
|
+
import noop from 'lodash/noop';
|
|
20
|
+
import 'react-responsive-tabs/styles.css';
|
|
21
|
+
import '@eeacms/volto-tabs-block/less/menu.less';
|
|
22
|
+
|
|
23
|
+
const MenuItem = (props) => {
|
|
24
|
+
const inputRef = React.useRef(null);
|
|
25
|
+
const {
|
|
26
|
+
activeTab = null,
|
|
27
|
+
activeBlock = null,
|
|
28
|
+
block = null,
|
|
29
|
+
data = {},
|
|
30
|
+
editingTab = null,
|
|
31
|
+
selected = false,
|
|
32
|
+
tabData = {},
|
|
33
|
+
tabs = {},
|
|
34
|
+
|
|
35
|
+
tabsData = {},
|
|
36
|
+
tabsDescription,
|
|
37
|
+
tabsList = [],
|
|
38
|
+
tabsTitle,
|
|
39
|
+
emptyTab = noop,
|
|
40
|
+
setActiveBlock = noop,
|
|
41
|
+
setActiveTab = noop,
|
|
42
|
+
setEditingTab = noop,
|
|
43
|
+
onChangeBlock = noop,
|
|
44
|
+
} = props;
|
|
45
|
+
const { tab, index } = props;
|
|
46
|
+
const tabIndex = index + 1;
|
|
47
|
+
const defaultTitle = `Tab ${tabIndex}`;
|
|
48
|
+
const title = tabs[tab]?.title;
|
|
49
|
+
const addNewTab = () => {
|
|
50
|
+
const tabId = uuid();
|
|
51
|
+
|
|
52
|
+
onChangeBlock(block, {
|
|
53
|
+
...data,
|
|
54
|
+
data: {
|
|
55
|
+
...tabsData,
|
|
56
|
+
blocks: {
|
|
57
|
+
...tabsData.blocks,
|
|
58
|
+
[tabId]: {
|
|
59
|
+
...emptyTab(),
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
blocks_layout: {
|
|
63
|
+
items: [...tabsData.blocks_layout.items, tabId],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
React.useEffect(() => {
|
|
70
|
+
if (editingTab === tab && inputRef.current) {
|
|
71
|
+
inputRef.current.focus();
|
|
72
|
+
}
|
|
73
|
+
/* eslint-disable-next-line */
|
|
74
|
+
}, [editingTab]);
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
{index === 0 && (tabsTitle || tabsDescription) && (
|
|
79
|
+
<div className="menu-title"></div>
|
|
80
|
+
)}
|
|
81
|
+
|
|
82
|
+
<Menu.Item
|
|
83
|
+
role="tab"
|
|
84
|
+
aria-hidden="true"
|
|
85
|
+
name={defaultTitle}
|
|
86
|
+
active={tab === activeTab}
|
|
87
|
+
onClick={() => {
|
|
88
|
+
if (activeTab !== tab) {
|
|
89
|
+
setActiveTab(tab);
|
|
90
|
+
}
|
|
91
|
+
if (activeBlock) {
|
|
92
|
+
setActiveBlock(null);
|
|
93
|
+
}
|
|
94
|
+
if (editingTab !== tab) {
|
|
95
|
+
setEditingTab(null);
|
|
96
|
+
}
|
|
97
|
+
}}
|
|
98
|
+
onDoubleClick={() => {
|
|
99
|
+
setEditingTab(tab);
|
|
100
|
+
}}
|
|
101
|
+
className="remove-margin"
|
|
102
|
+
>
|
|
103
|
+
{editingTab === tab && selected ? (
|
|
104
|
+
<Input
|
|
105
|
+
placeholder={defaultTitle}
|
|
106
|
+
ref={inputRef}
|
|
107
|
+
transparent
|
|
108
|
+
value={title}
|
|
109
|
+
onChange={(e) => {
|
|
110
|
+
onChangeBlock(block, {
|
|
111
|
+
...data,
|
|
112
|
+
data: {
|
|
113
|
+
...tabsData,
|
|
114
|
+
blocks: {
|
|
115
|
+
...tabsData.blocks,
|
|
116
|
+
[tab]: {
|
|
117
|
+
...(tabData || {}),
|
|
118
|
+
title: e.target.value,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
) : (
|
|
126
|
+
<>
|
|
127
|
+
<p className={'menu-item-text'}>{title || defaultTitle}</p>
|
|
128
|
+
</>
|
|
129
|
+
)}
|
|
130
|
+
</Menu.Item>
|
|
131
|
+
{index === tabsList.length - 1 ? (
|
|
132
|
+
<>
|
|
133
|
+
<Menu.Item
|
|
134
|
+
role="tab"
|
|
135
|
+
aria-hidden="true"
|
|
136
|
+
name="addition"
|
|
137
|
+
onClick={() => {
|
|
138
|
+
addNewTab();
|
|
139
|
+
setEditingTab(null);
|
|
140
|
+
}}
|
|
141
|
+
className="remove-margin addition-button"
|
|
142
|
+
>
|
|
143
|
+
<p className={'menu-item-text'}>+</p>
|
|
144
|
+
</Menu.Item>
|
|
145
|
+
</>
|
|
146
|
+
) : (
|
|
147
|
+
''
|
|
148
|
+
)}
|
|
149
|
+
</>
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
class Tab extends React.Component {
|
|
154
|
+
constructor() {
|
|
155
|
+
super();
|
|
156
|
+
this.state = {
|
|
157
|
+
height: 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
componentDidMount() {
|
|
162
|
+
if (this.state.height === 0) {
|
|
163
|
+
requestAnimationFrame(() => {
|
|
164
|
+
this.setState({ height: 'auto' });
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
render() {
|
|
170
|
+
return (
|
|
171
|
+
<AnimateHeight
|
|
172
|
+
animateOpacity
|
|
173
|
+
duration={500}
|
|
174
|
+
height={this.state.height}
|
|
175
|
+
aria-hidden={false}
|
|
176
|
+
>
|
|
177
|
+
{this.props.children}
|
|
178
|
+
</AnimateHeight>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
2
182
|
|
|
3
183
|
const Edit = (props) => {
|
|
184
|
+
const {
|
|
185
|
+
data = {},
|
|
186
|
+
tabsList = [],
|
|
187
|
+
tabs = {},
|
|
188
|
+
activeTabIndex = 0,
|
|
189
|
+
setActiveTab = noop,
|
|
190
|
+
editingTab = null,
|
|
191
|
+
activeBlock = null,
|
|
192
|
+
activeTab = null,
|
|
193
|
+
block = null,
|
|
194
|
+
setEditingTab = noop,
|
|
195
|
+
multiSelected = [],
|
|
196
|
+
manage = false,
|
|
197
|
+
metadata = null,
|
|
198
|
+
selected = false,
|
|
199
|
+
onChangeBlock = noop,
|
|
200
|
+
onChangeTabData = noop,
|
|
201
|
+
onSelectBlock = noop,
|
|
202
|
+
emptyTab = noop,
|
|
203
|
+
tabsData = {},
|
|
204
|
+
} = props;
|
|
205
|
+
|
|
206
|
+
const accordionConfig =
|
|
207
|
+
config.blocks.blocksConfig[TABS_BLOCK].templates?.['accordion'] || {};
|
|
208
|
+
const { icons, semanticIcon, transformWidth = 800 } = accordionConfig;
|
|
209
|
+
|
|
210
|
+
const tabsContainer = React.useRef();
|
|
211
|
+
const [mounted, setMounted] = React.useState(false);
|
|
212
|
+
const [hashTab, setHashTab] = React.useState(false);
|
|
213
|
+
const [initialWidth, setInitialWidth] = React.useState(transformWidth);
|
|
214
|
+
|
|
215
|
+
const schema = React.useMemo(
|
|
216
|
+
() =>
|
|
217
|
+
config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
|
|
218
|
+
config,
|
|
219
|
+
props,
|
|
220
|
+
) || {},
|
|
221
|
+
[props],
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const getDataValue = React.useCallback(
|
|
225
|
+
(key) => {
|
|
226
|
+
return (
|
|
227
|
+
(schema.properties[key]?.value || data[key]) ??
|
|
228
|
+
schema.properties[key]?.defaultValue
|
|
229
|
+
);
|
|
230
|
+
},
|
|
231
|
+
[schema, data],
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
const items = tabsList.map((tab, index) => {
|
|
235
|
+
const title = tabs[tab]?.title;
|
|
236
|
+
const defaultTitle = `Tab ${index + 1}`;
|
|
237
|
+
const active = activeTabIndex === index;
|
|
238
|
+
const tabsDescription = data.description;
|
|
239
|
+
|
|
240
|
+
return {
|
|
241
|
+
title: (
|
|
242
|
+
<>
|
|
243
|
+
{semanticIcon ? (
|
|
244
|
+
<div className="tabs-icon">
|
|
245
|
+
<Icon
|
|
246
|
+
className={active ? semanticIcon.opened : semanticIcon.closed}
|
|
247
|
+
/>
|
|
248
|
+
</div>
|
|
249
|
+
) : (
|
|
250
|
+
<div className="tabs-icon">
|
|
251
|
+
<VoltoIcon
|
|
252
|
+
name={active ? icons.opened : icons.closed}
|
|
253
|
+
size={icons.size}
|
|
254
|
+
className="tabs-icon"
|
|
255
|
+
/>
|
|
256
|
+
</div>
|
|
257
|
+
)}
|
|
258
|
+
<MenuItem
|
|
259
|
+
{...props}
|
|
260
|
+
key={tab}
|
|
261
|
+
editingTab={editingTab}
|
|
262
|
+
index={index}
|
|
263
|
+
setEditingTab={setEditingTab}
|
|
264
|
+
tab={tab}
|
|
265
|
+
tabsTitle={title || defaultTitle}
|
|
266
|
+
tabsDescription={tabsDescription}
|
|
267
|
+
/>
|
|
268
|
+
</>
|
|
269
|
+
),
|
|
270
|
+
content: (
|
|
271
|
+
<Tab {...props} tab={tab} content={tabs[tab]} aria-hidden={false}>
|
|
272
|
+
<BlocksForm
|
|
273
|
+
allowedBlocks={data?.allowedBlocks}
|
|
274
|
+
description={data?.instrunctions?.data}
|
|
275
|
+
manage={manage}
|
|
276
|
+
metadata={metadata}
|
|
277
|
+
pathname={props.pathname}
|
|
278
|
+
properties={isEmpty(tabs[tab]) ? emptyBlocksForm() : tabs[tab]}
|
|
279
|
+
selected={selected && activeTab === tab && activeBlock}
|
|
280
|
+
selectedBlock={
|
|
281
|
+
selected && activeTab === tab && activeBlock ? activeBlock : null
|
|
282
|
+
}
|
|
283
|
+
title={data?.placeholder}
|
|
284
|
+
onChangeField={onChangeTabData}
|
|
285
|
+
onChangeFormData={(newFormData) => {
|
|
286
|
+
onChangeBlock(block, {
|
|
287
|
+
...data,
|
|
288
|
+
data: {
|
|
289
|
+
...tabsData,
|
|
290
|
+
blocks: {
|
|
291
|
+
...tabsData.blocks,
|
|
292
|
+
[activeTab]: {
|
|
293
|
+
...(newFormData.blocks_layout.items.length > 0
|
|
294
|
+
? newFormData
|
|
295
|
+
: emptyTab()),
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
}}
|
|
301
|
+
onSelectBlock={(id, selected, e) => {
|
|
302
|
+
const isMultipleSelection = e
|
|
303
|
+
? e.shiftKey || e.ctrlKey || e.metaKey
|
|
304
|
+
: false;
|
|
305
|
+
onSelectBlock(
|
|
306
|
+
id,
|
|
307
|
+
activeBlock === id ? false : isMultipleSelection,
|
|
308
|
+
e,
|
|
309
|
+
);
|
|
310
|
+
setEditingTab(null);
|
|
311
|
+
}}
|
|
312
|
+
>
|
|
313
|
+
{({ draginfo }, editBlock, blockProps) => {
|
|
314
|
+
return (
|
|
315
|
+
<EditBlockWrapper
|
|
316
|
+
blockProps={blockProps}
|
|
317
|
+
draginfo={draginfo}
|
|
318
|
+
multiSelected={multiSelected.includes(blockProps.block)}
|
|
319
|
+
>
|
|
320
|
+
{editBlock}
|
|
321
|
+
</EditBlockWrapper>
|
|
322
|
+
);
|
|
323
|
+
}}
|
|
324
|
+
</BlocksForm>
|
|
325
|
+
</Tab>
|
|
326
|
+
),
|
|
327
|
+
key: tab,
|
|
328
|
+
tabClassName: cx('ui button item title', { active }, 'remove-menu'),
|
|
329
|
+
panelClassName: cx('ui bottom attached segment tab', {
|
|
330
|
+
active,
|
|
331
|
+
}),
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
React.useEffect(() => {
|
|
336
|
+
setMounted(true);
|
|
337
|
+
}, []);
|
|
338
|
+
React.useEffect(() => {
|
|
339
|
+
if (!mounted) return;
|
|
340
|
+
const { blockWidth, tabsTotalWidth } = tabsContainer.current?.state || {};
|
|
341
|
+
setInitialWidth(
|
|
342
|
+
tabsTotalWidth < blockWidth ? tabsTotalWidth + 1 : blockWidth + 1,
|
|
343
|
+
);
|
|
344
|
+
}, [mounted]);
|
|
345
|
+
|
|
4
346
|
return (
|
|
5
|
-
<
|
|
6
|
-
{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
347
|
+
<Tabs
|
|
348
|
+
ref={tabsContainer}
|
|
349
|
+
transformWidth={initialWidth}
|
|
350
|
+
selectedTabKey={tabsList[activeTabIndex]}
|
|
351
|
+
unmountOnExit={false}
|
|
352
|
+
items={items}
|
|
353
|
+
onChange={(tab) => {
|
|
354
|
+
const { blockWidth } = tabsContainer.current?.state || {};
|
|
355
|
+
const tabWithHash = getParentTabFromHash(
|
|
356
|
+
data,
|
|
357
|
+
props.location.hash.substring(1),
|
|
358
|
+
);
|
|
359
|
+
if (tabWithHash === tabsList[activeTabIndex] && !hashTab)
|
|
360
|
+
setHashTab(true);
|
|
361
|
+
else if (tab !== tabsList[activeTabIndex]) {
|
|
362
|
+
setActiveTab(tab);
|
|
363
|
+
} else if (blockWidth <= initialWidth) {
|
|
364
|
+
setActiveTab(null);
|
|
365
|
+
}
|
|
13
366
|
}}
|
|
367
|
+
tabsWrapperClass={cx(
|
|
368
|
+
props?.data?.accordionIconRight ? 'tabs-accordion-icon-right' : '',
|
|
369
|
+
'ui pointing secondary menu',
|
|
370
|
+
'tabs-accessibility',
|
|
371
|
+
data?.theme ? `theme-${data?.theme}` : '',
|
|
372
|
+
{
|
|
373
|
+
inverted: getDataValue('menuInverted'),
|
|
374
|
+
},
|
|
375
|
+
'ui fluid pointing secondary menu',
|
|
376
|
+
)}
|
|
377
|
+
showMore={false}
|
|
14
378
|
/>
|
|
15
379
|
);
|
|
16
380
|
};
|
|
17
381
|
|
|
18
|
-
export default Edit;
|
|
382
|
+
export default compose(withScrollToTarget, withRouter)(Edit);
|
|
@@ -33,14 +33,16 @@ class Tab extends React.Component {
|
|
|
33
33
|
|
|
34
34
|
render() {
|
|
35
35
|
return (
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
<div id={this.props.title} className="tab-name">
|
|
37
|
+
<AnimateHeight
|
|
38
|
+
animateOpacity
|
|
39
|
+
duration={500}
|
|
40
|
+
height={this.state.height}
|
|
41
|
+
aria-hidden={false}
|
|
42
|
+
>
|
|
43
|
+
<RenderBlocks {...this.props} />
|
|
44
|
+
</AnimateHeight>
|
|
45
|
+
</div>
|
|
44
46
|
);
|
|
45
47
|
}
|
|
46
48
|
}
|
|
@@ -105,7 +107,13 @@ const View = (props) => {
|
|
|
105
107
|
</>
|
|
106
108
|
),
|
|
107
109
|
content: (
|
|
108
|
-
<Tab
|
|
110
|
+
<Tab
|
|
111
|
+
{...props}
|
|
112
|
+
tab={tab}
|
|
113
|
+
content={tabs[tab]}
|
|
114
|
+
aria-hidden={false}
|
|
115
|
+
title={tabs[tab]?.title || `Tab ${tabsList.indexOf(tab) + 1}`}
|
|
116
|
+
/>
|
|
109
117
|
),
|
|
110
118
|
key: tab,
|
|
111
119
|
tabClassName: cx('ui button item title', { active }),
|
|
@@ -141,7 +149,6 @@ const View = (props) => {
|
|
|
141
149
|
activeTabDiv.focus();
|
|
142
150
|
}
|
|
143
151
|
}, [activeTabIndex, id]);
|
|
144
|
-
|
|
145
152
|
return (
|
|
146
153
|
<div
|
|
147
154
|
tabIndex="0"
|
|
@@ -111,9 +111,9 @@ const View = (props) => {
|
|
|
111
111
|
dots: false,
|
|
112
112
|
speed: 500,
|
|
113
113
|
initialSlide: 0,
|
|
114
|
-
lazyLoad: 'ondemand',
|
|
115
114
|
swipe: true,
|
|
116
115
|
slidesToShow: 1,
|
|
116
|
+
lazyLoad: false,
|
|
117
117
|
slidesToScroll: 1,
|
|
118
118
|
touchMove: true,
|
|
119
119
|
beforeChange: (oldIndex, index) => {
|
|
@@ -29,7 +29,6 @@ const MenuItem = (props) => {
|
|
|
29
29
|
const { tab, index } = props;
|
|
30
30
|
const title = tabs[tab].title;
|
|
31
31
|
const tabIndex = index + 1;
|
|
32
|
-
|
|
33
32
|
const [tabChanged, setTabChanged] = useState(false);
|
|
34
33
|
const defaultTitle = `Tab ${tabIndex}`;
|
|
35
34
|
|
|
@@ -45,6 +44,7 @@ const MenuItem = (props) => {
|
|
|
45
44
|
setTabChanged(false);
|
|
46
45
|
}
|
|
47
46
|
}, [tabChanged, tab, blockId]);
|
|
47
|
+
|
|
48
48
|
return (
|
|
49
49
|
<React.Fragment>
|
|
50
50
|
{index === 0 && (tabsTitle || tabsDescription) && (
|
|
@@ -88,7 +88,6 @@ const View = (props) => {
|
|
|
88
88
|
activeTabIndex = 0,
|
|
89
89
|
} = props;
|
|
90
90
|
const [menuPosition, setMenuPosition] = React.useState({});
|
|
91
|
-
|
|
92
91
|
React.useEffect(() => {
|
|
93
92
|
if (Object.keys(menuPosition).length === 0) {
|
|
94
93
|
setMenuPosition(getMenuPosition(data));
|
|
@@ -134,8 +133,17 @@ const View = (props) => {
|
|
|
134
133
|
),
|
|
135
134
|
pane: (
|
|
136
135
|
<Tab.Pane as={isContainer ? Container : undefined}>
|
|
137
|
-
<div
|
|
138
|
-
|
|
136
|
+
<div
|
|
137
|
+
id={tabs[tab]?.title || `Tab ${tabsList.indexOf(tab) + 1}`}
|
|
138
|
+
className="tab-name"
|
|
139
|
+
>
|
|
140
|
+
<div tabIndex={0} role="tabpanel" id={'tab-pane-' + tab}>
|
|
141
|
+
<RenderBlocks
|
|
142
|
+
{...props}
|
|
143
|
+
metadata={metadata}
|
|
144
|
+
content={tabs[tab]}
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
139
147
|
</div>
|
|
140
148
|
</Tab.Pane>
|
|
141
149
|
),
|