@eeacms/volto-tabs-block 1.2.11 → 1.3.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.md +30 -1
- package/Jenkinsfile +3 -3
- package/cypress/integration/block-basics.js +5 -6
- package/package.json +1 -1
- package/src/components/Edit.jsx +13 -4
- package/src/components/View.jsx +4 -3
- package/src/components/index.js +1 -0
- package/src/components/schema.js +6 -6
- package/src/components/templates/carousel/HorizontalView.jsx +3 -1
- package/src/components/templates/carousel/VerticalView.jsx +1 -1
- package/src/components/templates/default/Edit.jsx +67 -35
- package/src/components/templates/default/View.jsx +84 -43
- package/src/components/templates/default/schema.js +92 -11
- package/src/components/templates/horizontal-responsive/View.jsx +277 -0
- package/src/components/templates/horizontal-responsive/index.js +4 -0
- package/src/components/templates/horizontal-responsive/schema.js +123 -0
- package/src/index.js +8 -0
- package/src/less/carousel.less +1 -6
- package/src/less/edit.less +145 -0
- package/src/less/menu.less +52 -173
- package/src/less/menu.variables +6 -27
- package/src/less/tabs.less +65 -0
- package/src/less/tabs.variables +9 -0
- package/src/utils/dimensions.js +76 -0
- package/src/utils/index.js +41 -1
- package/src/less/tabs-block.less +0 -298
package/CHANGELOG.md
CHANGED
|
@@ -4,9 +4,38 @@ 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
|
+
#### [1.3.1](https://github.com/eea/volto-tabs-block/compare/1.3.0...1.3.1)
|
|
8
|
+
|
|
9
|
+
- Style fix + missing key [`0d2b097`](https://github.com/eea/volto-tabs-block/commit/0d2b097850bc89d8a525ce8a4564a348975d33b9)
|
|
10
|
+
|
|
11
|
+
#### [1.3.0](https://github.com/eea/volto-tabs-block/compare/1.2.12...1.3.0)
|
|
12
|
+
|
|
13
|
+
> 6 April 2022
|
|
14
|
+
|
|
15
|
+
- Refactor tabs block [`#19`](https://github.com/eea/volto-tabs-block/pull/19)
|
|
16
|
+
- Refactor tabs block [`#18`](https://github.com/eea/volto-tabs-block/pull/18)
|
|
17
|
+
- Fix tests [`fdc74d9`](https://github.com/eea/volto-tabs-block/commit/fdc74d9f5f1c851de9ca3a9576cf2dbcd1495968)
|
|
18
|
+
- Bump version [`acfef41`](https://github.com/eea/volto-tabs-block/commit/acfef413eb9f923f7a7283d12417e23c81192633)
|
|
19
|
+
- Change z-index for slide-arrows [`97baed1`](https://github.com/eea/volto-tabs-block/commit/97baed1c11b90d043cb5f772c65dcaee24278ca3)
|
|
20
|
+
- update [`26bfd0e`](https://github.com/eea/volto-tabs-block/commit/26bfd0e00aded4bef827b57c7e0d9036540a7ee7)
|
|
21
|
+
- update [`542d0cd`](https://github.com/eea/volto-tabs-block/commit/542d0cd14e8164d20d8cb8dd7416d108fbaa88d5)
|
|
22
|
+
- Make horizontal-responsive work [`bb1d81e`](https://github.com/eea/volto-tabs-block/commit/bb1d81e858d01c409ce86f19974c60cbd764b717)
|
|
23
|
+
- Add horizontal responsive template [`c6e6cca`](https://github.com/eea/volto-tabs-block/commit/c6e6cca355c6164a26e7aec291e4a0223625ea91)
|
|
24
|
+
- Let theme addon to set default values for default template schema [`55f148d`](https://github.com/eea/volto-tabs-block/commit/55f148d1a95417f8a0b55681ce250acde8463c1c)
|
|
25
|
+
- Render pane as container if tabs-block has full-width class [`bbffb96`](https://github.com/eea/volto-tabs-block/commit/bbffb96b908476ddee447af3ce79bafb1a12f9a8)
|
|
26
|
+
- Refactor default template [`58eff52`](https://github.com/eea/volto-tabs-block/commit/58eff5281adb08a5f8fe6d21fd43330252012277)
|
|
27
|
+
|
|
28
|
+
#### [1.2.12](https://github.com/eea/volto-tabs-block/compare/1.2.11...1.2.12)
|
|
29
|
+
|
|
30
|
+
> 21 January 2022
|
|
31
|
+
|
|
32
|
+
- Make sure metadata block works within Tabs block [`#17`](https://github.com/eea/volto-tabs-block/pull/17)
|
|
33
|
+
|
|
7
34
|
#### [1.2.11](https://github.com/eea/volto-tabs-block/compare/1.2.10...1.2.11)
|
|
8
35
|
|
|
9
|
-
|
|
36
|
+
> 4 January 2022
|
|
37
|
+
|
|
38
|
+
- Fix cypress tests when using with volto-slate [`#16`](https://github.com/eea/volto-tabs-block/pull/16)
|
|
10
39
|
|
|
11
40
|
#### [1.2.10](https://github.com/eea/volto-tabs-block/compare/1.2.9...1.2.10)
|
|
12
41
|
|
package/Jenkinsfile
CHANGED
|
@@ -4,7 +4,7 @@ pipeline {
|
|
|
4
4
|
environment {
|
|
5
5
|
GIT_NAME = "volto-tabs-block"
|
|
6
6
|
NAMESPACE = "@eeacms"
|
|
7
|
-
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,biodiversity.europa.eu,www.eea.europa.eu-ims,sustainability.eionet.europa.eu,forest.eea.europa.eu,clms.land.copernicus.eu,industry.eea.europa.eu,water.europa.eu-freshwater"
|
|
7
|
+
SONARQUBE_TAGS = "volto.eea.europa.eu,climate-energy.eea.europa.eu,biodiversity.europa.eu,www.eea.europa.eu-ims,sustainability.eionet.europa.eu,forest.eea.europa.eu,clms.land.copernicus.eu,industry.eea.europa.eu,water.europa.eu-freshwater,demo-www.eea.europa.eu,clmsdemo.devel6cph.eea.europa.eu"
|
|
8
8
|
DEPENDENCIES = "@eeacms/volto-block-style"
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -184,10 +184,10 @@ pipeline {
|
|
|
184
184
|
unstash "xunit-reports"
|
|
185
185
|
unstash "cypress-coverage"
|
|
186
186
|
def scannerHome = tool 'SonarQubeScanner';
|
|
187
|
-
def nodeJS = tool '
|
|
187
|
+
def nodeJS = tool 'NodeJS';
|
|
188
188
|
withSonarQubeEnv('Sonarqube') {
|
|
189
189
|
sh '''sed -i "s#/opt/frontend/my-volto-project/src/addons/${GIT_NAME}/##g" xunit-reports/coverage/lcov.info'''
|
|
190
|
-
sh "export PATH=$
|
|
190
|
+
sh "export PATH=${scannerHome}/bin:${nodeJS}/bin:$PATH; sonar-scanner -Dsonar.javascript.lcov.reportPaths=./xunit-reports/coverage/lcov.info,./cypress-coverage/coverage/lcov.info -Dsonar.sources=./src -Dsonar.projectKey=$GIT_NAME-$BRANCH_NAME -Dsonar.projectVersion=$BRANCH_NAME-$BUILD_NUMBER"
|
|
191
191
|
sh '''try=2; while [ \$try -gt 0 ]; do curl -s -XPOST -u "${SONAR_AUTH_TOKEN}:" "${SONAR_HOST_URL}api/project_tags/set?project=${GIT_NAME}-${BRANCH_NAME}&tags=${SONARQUBE_TAGS},${BRANCH_NAME}" > set_tags_result; if [ \$(grep -ic error set_tags_result ) -eq 0 ]; then try=0; else cat set_tags_result; echo "... Will retry"; sleep 60; try=\$(( \$try - 1 )); fi; done'''
|
|
192
192
|
}
|
|
193
193
|
}
|
|
@@ -36,14 +36,13 @@ describe('Blocks Tests', () => {
|
|
|
36
36
|
cy.get('.field-wrapper-menuAlign #field-menuAlign').click();
|
|
37
37
|
cy.get('.react-select__menu').contains('Left').click();
|
|
38
38
|
cy.get('.field-wrapper-menuPosition #field-menuPosition').first().click();
|
|
39
|
-
cy.get('.react-select__menu').contains('
|
|
39
|
+
cy.get('.react-select__menu').contains('Top').click();
|
|
40
40
|
|
|
41
41
|
cy.get('[contenteditable=true]').first().focus().click();
|
|
42
|
-
cy.get('.tabs-block [contenteditable=true]').first().type(
|
|
42
|
+
cy.get('.tabs-block [contenteditable=true]').first().type('Hydrogen');
|
|
43
43
|
cy.get('.tabs-block .ui.left.menu .item').last().click();
|
|
44
44
|
cy.get('.tabs-block').contains('Tab 2').click();
|
|
45
|
-
cy.get('.tabs-block.edit [contenteditable=true]').first().type(
|
|
46
|
-
|
|
45
|
+
cy.get('.tabs-block.edit [contenteditable=true]').first().type('Oxygen');
|
|
47
46
|
|
|
48
47
|
cy.get('[contenteditable=true]').first().type('{enter}');
|
|
49
48
|
cy.get('.ui.basic.icon.button.block-add-button').first().click();
|
|
@@ -56,8 +55,8 @@ describe('Blocks Tests', () => {
|
|
|
56
55
|
cy.get('.react-select__menu').contains('Bottom').click();
|
|
57
56
|
cy.get('.field-wrapper-theme #field-theme').click();
|
|
58
57
|
cy.get('.react-select__menu').contains('Dark').click();
|
|
59
|
-
cy.get('.tabs-block .ui.
|
|
60
|
-
|
|
58
|
+
cy.get('.tabs-block .ui.menu .item').last().click();
|
|
59
|
+
cy.get('.tabs-block .ui.menu .item').eq(1).click();
|
|
61
60
|
|
|
62
61
|
// Save
|
|
63
62
|
cy.get('#toolbar-save').click();
|
package/package.json
CHANGED
package/src/components/Edit.jsx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { without } from 'lodash';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import config from '@plone/volto/registry';
|
|
3
5
|
import { SidebarPortal, BlocksToolbar } from '@plone/volto/components';
|
|
4
6
|
import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
|
|
5
7
|
import { getBlocksLayoutFieldname } from '@plone/volto/helpers';
|
|
@@ -9,12 +11,12 @@ import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
|
|
|
9
11
|
import { BlockStyleWrapperEdit } from '@eeacms/volto-block-style/BlockStyleWrapper';
|
|
10
12
|
import { DefaultEdit } from './templates/default';
|
|
11
13
|
import { schema } from './schema';
|
|
12
|
-
import cx from 'classnames';
|
|
13
14
|
|
|
14
|
-
import
|
|
15
|
+
import '@eeacms/volto-tabs-block/less/edit.less';
|
|
16
|
+
import '@eeacms/volto-tabs-block/less/tabs.less';
|
|
15
17
|
|
|
16
18
|
const Edit = (props) => {
|
|
17
|
-
const { onChangeBlock } = props;
|
|
19
|
+
const { onChangeBlock, onChangeField } = props;
|
|
18
20
|
const { data = {}, block = null } = props;
|
|
19
21
|
const template = data.template || 'default';
|
|
20
22
|
const tabsData = data.data || {};
|
|
@@ -36,7 +38,12 @@ const Edit = (props) => {
|
|
|
36
38
|
const templateSchema =
|
|
37
39
|
config.blocks.blocksConfig[TABS_BLOCK].templates?.[template]?.schema || {};
|
|
38
40
|
|
|
39
|
-
const schemaObject = schema(
|
|
41
|
+
const schemaObject = schema(
|
|
42
|
+
config,
|
|
43
|
+
typeof templateSchema === 'function'
|
|
44
|
+
? templateSchema(config, props)
|
|
45
|
+
: templateSchema,
|
|
46
|
+
);
|
|
40
47
|
|
|
41
48
|
React.useEffect(() => {
|
|
42
49
|
if (!Object.keys(data.data || {}).length) {
|
|
@@ -99,6 +106,8 @@ const Edit = (props) => {
|
|
|
99
106
|
},
|
|
100
107
|
},
|
|
101
108
|
});
|
|
109
|
+
} else {
|
|
110
|
+
onChangeField(id, value);
|
|
102
111
|
}
|
|
103
112
|
};
|
|
104
113
|
|
package/src/components/View.jsx
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import cx from 'classnames';
|
|
3
|
+
import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
|
|
2
4
|
import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
|
|
3
5
|
import { DefaultView } from './templates/default';
|
|
4
|
-
import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
|
|
5
|
-
import cx from 'classnames';
|
|
6
6
|
|
|
7
7
|
import config from '@plone/volto/registry';
|
|
8
8
|
|
|
9
|
-
import '@eeacms/volto-tabs-block/less/
|
|
9
|
+
import '@eeacms/volto-tabs-block/less/edit.less';
|
|
10
|
+
import '@eeacms/volto-tabs-block/less/tabs.less';
|
|
10
11
|
|
|
11
12
|
const View = (props) => {
|
|
12
13
|
const view = React.useRef(null);
|
package/src/components/index.js
CHANGED
package/src/components/schema.js
CHANGED
|
@@ -7,12 +7,12 @@ export const schema = (config, templateSchema = {}) => {
|
|
|
7
7
|
templatesConfig[template].title || template,
|
|
8
8
|
]);
|
|
9
9
|
|
|
10
|
-
const defaultFieldset = templateSchema
|
|
10
|
+
const defaultFieldset = templateSchema?.fieldsets?.filter(
|
|
11
11
|
(fieldset) => fieldset.id === 'default',
|
|
12
12
|
)[0];
|
|
13
13
|
|
|
14
14
|
return {
|
|
15
|
-
title: templateSchema
|
|
15
|
+
title: templateSchema?.title || 'Tabs block',
|
|
16
16
|
fieldsets: [
|
|
17
17
|
{
|
|
18
18
|
id: 'default',
|
|
@@ -22,10 +22,10 @@ export const schema = (config, templateSchema = {}) => {
|
|
|
22
22
|
'title',
|
|
23
23
|
'template',
|
|
24
24
|
'verticalAlign',
|
|
25
|
-
...(defaultFieldset?.fields ||
|
|
25
|
+
...(defaultFieldset?.fields || []),
|
|
26
26
|
],
|
|
27
27
|
},
|
|
28
|
-
...(templateSchema
|
|
28
|
+
...(templateSchema?.fieldsets?.filter(
|
|
29
29
|
(fieldset) => fieldset.id !== 'default',
|
|
30
30
|
) || []),
|
|
31
31
|
],
|
|
@@ -53,8 +53,8 @@ export const schema = (config, templateSchema = {}) => {
|
|
|
53
53
|
],
|
|
54
54
|
default: 'flex-start',
|
|
55
55
|
},
|
|
56
|
-
...(templateSchema
|
|
56
|
+
...(templateSchema?.properties || {}),
|
|
57
57
|
},
|
|
58
|
-
required: [...(templateSchema
|
|
58
|
+
required: [...(templateSchema?.required || [])],
|
|
59
59
|
};
|
|
60
60
|
};
|
|
@@ -3,11 +3,13 @@ import { connect } from 'react-redux';
|
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import { withRouter } from 'react-router';
|
|
5
5
|
import loadable from '@loadable/component';
|
|
6
|
+
import cx from 'classnames';
|
|
6
7
|
import { Icon, RenderBlocks } from '@plone/volto/components';
|
|
7
8
|
import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
|
|
9
|
+
|
|
8
10
|
import rightArrowSVG from '@eeacms/volto-tabs-block/icons/right-arrow.svg';
|
|
9
11
|
import leftArrowSVG from '@eeacms/volto-tabs-block/icons/left-arrow.svg';
|
|
10
|
-
|
|
12
|
+
|
|
11
13
|
import 'slick-carousel/slick/slick.css';
|
|
12
14
|
import 'slick-carousel/slick/slick-theme.css';
|
|
13
15
|
import '@eeacms/volto-tabs-block/less/carousel.less';
|
|
@@ -3,9 +3,9 @@ import { connect } from 'react-redux';
|
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import { withRouter } from 'react-router';
|
|
5
5
|
import loadable from '@loadable/component';
|
|
6
|
+
import cx from 'classnames';
|
|
6
7
|
import { RenderBlocks } from '@plone/volto/components';
|
|
7
8
|
import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
|
|
8
|
-
import cx from 'classnames';
|
|
9
9
|
|
|
10
10
|
import 'slick-carousel/slick/slick.css';
|
|
11
11
|
import 'slick-carousel/slick/slick-theme.css';
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { isEmpty } from 'lodash';
|
|
3
3
|
import { v4 as uuid } from 'uuid';
|
|
4
|
-
import
|
|
4
|
+
import cx from 'classnames';
|
|
5
|
+
import { Menu, Tab, Input, Container } from 'semantic-ui-react';
|
|
6
|
+
import config from '@plone/volto/registry';
|
|
5
7
|
import { BlocksForm } from '@plone/volto/components';
|
|
6
8
|
import { emptyBlocksForm } from '@plone/volto/helpers';
|
|
9
|
+
import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
|
|
7
10
|
import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
|
|
8
|
-
import {
|
|
9
|
-
|
|
11
|
+
import {
|
|
12
|
+
SimpleMarkdown,
|
|
13
|
+
getMenuPosition,
|
|
14
|
+
} from '@eeacms/volto-tabs-block/utils';
|
|
10
15
|
|
|
11
16
|
import '@eeacms/volto-tabs-block/less/menu.less';
|
|
12
17
|
|
|
@@ -19,10 +24,12 @@ const MenuItem = (props) => {
|
|
|
19
24
|
data = {},
|
|
20
25
|
editingTab = null,
|
|
21
26
|
selected = false,
|
|
22
|
-
tabs = {},
|
|
23
27
|
tabData = {},
|
|
28
|
+
tabs = {},
|
|
24
29
|
tabsData = {},
|
|
30
|
+
tabsDescription,
|
|
25
31
|
tabsList = [],
|
|
32
|
+
tabsTitle,
|
|
26
33
|
emptyTab = () => {},
|
|
27
34
|
setActiveBlock = () => {},
|
|
28
35
|
setActiveTab = () => {},
|
|
@@ -63,6 +70,12 @@ const MenuItem = (props) => {
|
|
|
63
70
|
|
|
64
71
|
return (
|
|
65
72
|
<>
|
|
73
|
+
{index === 0 && (tabsTitle || tabsDescription) && (
|
|
74
|
+
<Menu.Item className="menu-title">
|
|
75
|
+
<SimpleMarkdown md={tabsTitle} className="title" defaultTag="##" />
|
|
76
|
+
<SimpleMarkdown md={tabsDescription} className="description" />
|
|
77
|
+
</Menu.Item>
|
|
78
|
+
)}
|
|
66
79
|
<Menu.Item
|
|
67
80
|
name={defaultTitle}
|
|
68
81
|
active={tab === activeTab}
|
|
@@ -150,43 +163,47 @@ const Edit = (props) => {
|
|
|
150
163
|
onSelectBlock = () => {},
|
|
151
164
|
setEditingTab = () => {},
|
|
152
165
|
} = props;
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const menuPosition = data.menuPosition || 'inline';
|
|
166
|
+
const menuPosition = getMenuPosition(data);
|
|
167
|
+
const isContainer = data.align === 'full';
|
|
156
168
|
const tabsTitle = data.title;
|
|
157
169
|
const tabsDescription = data.description;
|
|
158
170
|
|
|
171
|
+
const schema = React.useMemo(
|
|
172
|
+
() =>
|
|
173
|
+
config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
|
|
174
|
+
config,
|
|
175
|
+
props,
|
|
176
|
+
) || {},
|
|
177
|
+
[props],
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
const getDataValue = React.useCallback(
|
|
181
|
+
(key) => {
|
|
182
|
+
return (
|
|
183
|
+
(schema.properties[key]?.value || data[key]) ??
|
|
184
|
+
schema.properties[key]?.defaultValue
|
|
185
|
+
);
|
|
186
|
+
},
|
|
187
|
+
[schema, data],
|
|
188
|
+
);
|
|
189
|
+
|
|
159
190
|
const panes = tabsList.map((tab, index) => {
|
|
160
191
|
return {
|
|
161
192
|
id: tab,
|
|
162
|
-
menuItem: (
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
</Menu.Item>
|
|
174
|
-
) : (
|
|
175
|
-
''
|
|
176
|
-
)}
|
|
177
|
-
<MenuItem
|
|
178
|
-
{...props}
|
|
179
|
-
editingTab={editingTab}
|
|
180
|
-
index={index}
|
|
181
|
-
setEditingTab={setEditingTab}
|
|
182
|
-
tab={tab}
|
|
183
|
-
/>
|
|
184
|
-
</React.Fragment>
|
|
185
|
-
);
|
|
186
|
-
},
|
|
193
|
+
menuItem: (
|
|
194
|
+
<MenuItem
|
|
195
|
+
{...props}
|
|
196
|
+
editingTab={editingTab}
|
|
197
|
+
index={index}
|
|
198
|
+
setEditingTab={setEditingTab}
|
|
199
|
+
tab={tab}
|
|
200
|
+
tabsTitle={tabsTitle}
|
|
201
|
+
tabsDescription={tabsDescription}
|
|
202
|
+
/>
|
|
203
|
+
),
|
|
187
204
|
render: () => {
|
|
188
205
|
return (
|
|
189
|
-
<Tab.Pane>
|
|
206
|
+
<Tab.Pane as={isContainer ? Container : undefined}>
|
|
190
207
|
<BlocksForm
|
|
191
208
|
allowedBlocks={data?.allowedBlocks}
|
|
192
209
|
description={data?.instrunctions?.data}
|
|
@@ -253,11 +270,26 @@ const Edit = (props) => {
|
|
|
253
270
|
<>
|
|
254
271
|
<Tab
|
|
255
272
|
activeIndex={activeTabIndex}
|
|
256
|
-
className=
|
|
273
|
+
className="default tabs"
|
|
257
274
|
menu={{
|
|
258
|
-
|
|
275
|
+
attached: menuPosition.attached,
|
|
276
|
+
borderless: getDataValue('menuBorderless'),
|
|
277
|
+
color: getDataValue('menuColor'),
|
|
278
|
+
compact: getDataValue('menuCompact'),
|
|
279
|
+
fluid: getDataValue('menuFluid'),
|
|
280
|
+
inverted: getDataValue('menuInverted'),
|
|
281
|
+
pointing: getDataValue('menuPointing'),
|
|
282
|
+
secondary: getDataValue('menuSecondary'),
|
|
283
|
+
size: getDataValue('menuSize'),
|
|
284
|
+
stackable: getDataValue('menuStackable'),
|
|
285
|
+
tabular: getDataValue('menuTabular'),
|
|
286
|
+
text: getDataValue('menuText'),
|
|
287
|
+
vertical: menuPosition.vertical,
|
|
288
|
+
className: cx(data.menuAlign, { container: isContainer }),
|
|
259
289
|
}}
|
|
290
|
+
menuPosition={menuPosition.direction}
|
|
260
291
|
panes={panes}
|
|
292
|
+
grid={{ paneWidth: 9, tabWidth: 3 }}
|
|
261
293
|
/>
|
|
262
294
|
</>
|
|
263
295
|
);
|
|
@@ -2,17 +2,27 @@ import React from 'react';
|
|
|
2
2
|
import { connect } from 'react-redux';
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import { withRouter } from 'react-router';
|
|
5
|
-
import
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import { Menu, Tab, Container } from 'semantic-ui-react';
|
|
7
|
+
import config from '@plone/volto/registry';
|
|
6
8
|
import { RenderBlocks } from '@plone/volto/components';
|
|
9
|
+
import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
|
|
7
10
|
import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
import {
|
|
12
|
+
SimpleMarkdown,
|
|
13
|
+
getMenuPosition,
|
|
14
|
+
} from '@eeacms/volto-tabs-block/utils';
|
|
11
15
|
|
|
12
16
|
import '@eeacms/volto-tabs-block/less/menu.less';
|
|
13
17
|
|
|
14
18
|
const MenuItem = (props) => {
|
|
15
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
activeTab = null,
|
|
21
|
+
tabs = {},
|
|
22
|
+
setActiveTab = () => {},
|
|
23
|
+
tabsTitle,
|
|
24
|
+
tabsDescription,
|
|
25
|
+
} = props;
|
|
16
26
|
const { tab, index } = props;
|
|
17
27
|
const title = tabs[tab].title;
|
|
18
28
|
const tabIndex = index + 1;
|
|
@@ -20,18 +30,26 @@ const MenuItem = (props) => {
|
|
|
20
30
|
const defaultTitle = `Tab ${tabIndex}`;
|
|
21
31
|
|
|
22
32
|
return (
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
<React.Fragment>
|
|
34
|
+
{index === 0 && (tabsTitle || tabsDescription) && (
|
|
35
|
+
<Menu.Item className="menu-title">
|
|
36
|
+
<SimpleMarkdown md={tabsTitle} defaultTag="##" className="title" />
|
|
37
|
+
<SimpleMarkdown md={tabsDescription} className="description" />
|
|
38
|
+
</Menu.Item>
|
|
39
|
+
)}
|
|
40
|
+
<Menu.Item
|
|
41
|
+
name={defaultTitle}
|
|
42
|
+
active={tab === activeTab}
|
|
43
|
+
onClick={() => {
|
|
44
|
+
if (activeTab !== tab) {
|
|
45
|
+
setActiveTab(tab);
|
|
46
|
+
}
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<span className={'menu-item-count'}>{tabIndex}</span>
|
|
50
|
+
<p className={'menu-item-text'}>{title || defaultTitle}</p>
|
|
51
|
+
</Menu.Item>
|
|
52
|
+
</React.Fragment>
|
|
35
53
|
);
|
|
36
54
|
};
|
|
37
55
|
|
|
@@ -46,12 +64,30 @@ const View = (props) => {
|
|
|
46
64
|
hashlink = {},
|
|
47
65
|
setActiveTab = () => {},
|
|
48
66
|
} = props;
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const menuPosition = data.menuPosition || 'inline';
|
|
67
|
+
const menuPosition = getMenuPosition(data);
|
|
68
|
+
const isContainer = data.align === 'full';
|
|
52
69
|
const tabsTitle = data.title;
|
|
53
70
|
const tabsDescription = data.description;
|
|
54
71
|
|
|
72
|
+
const schema = React.useMemo(
|
|
73
|
+
() =>
|
|
74
|
+
config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
|
|
75
|
+
config,
|
|
76
|
+
props,
|
|
77
|
+
) || {},
|
|
78
|
+
[props],
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
const getDataValue = React.useCallback(
|
|
82
|
+
(key) => {
|
|
83
|
+
return (
|
|
84
|
+
(schema.properties[key]?.value || data[key]) ??
|
|
85
|
+
schema.properties[key]?.defaultValue
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
[schema, data],
|
|
89
|
+
);
|
|
90
|
+
|
|
55
91
|
React.useEffect(() => {
|
|
56
92
|
const urlHash = props.location.hash.substring(1) || '';
|
|
57
93
|
if (
|
|
@@ -82,29 +118,19 @@ const View = (props) => {
|
|
|
82
118
|
const panes = tabsList.map((tab, index) => {
|
|
83
119
|
return {
|
|
84
120
|
id: tab,
|
|
85
|
-
menuItem: (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<SimpleMarkdown md={tabsDescription} className="description" />
|
|
96
|
-
</Menu.Item>
|
|
97
|
-
) : (
|
|
98
|
-
''
|
|
99
|
-
)}
|
|
100
|
-
<MenuItem {...props} tab={tab} index={index} />
|
|
101
|
-
</React.Fragment>
|
|
102
|
-
);
|
|
103
|
-
},
|
|
121
|
+
menuItem: (
|
|
122
|
+
<MenuItem
|
|
123
|
+
{...props}
|
|
124
|
+
key={tab}
|
|
125
|
+
tab={tab}
|
|
126
|
+
index={index}
|
|
127
|
+
tabsTitle={tabsTitle}
|
|
128
|
+
tabsDescription={tabsDescription}
|
|
129
|
+
/>
|
|
130
|
+
),
|
|
104
131
|
render: () => {
|
|
105
132
|
return (
|
|
106
|
-
<Tab.Pane
|
|
107
|
-
{' '}
|
|
133
|
+
<Tab.Pane as={isContainer ? Container : undefined}>
|
|
108
134
|
<RenderBlocks {...props} metadata={metadata} content={tabs[tab]} />
|
|
109
135
|
</Tab.Pane>
|
|
110
136
|
);
|
|
@@ -116,11 +142,26 @@ const View = (props) => {
|
|
|
116
142
|
<>
|
|
117
143
|
<Tab
|
|
118
144
|
activeIndex={activeTabIndex}
|
|
119
|
-
className=
|
|
145
|
+
className="default tabs"
|
|
120
146
|
menu={{
|
|
121
|
-
|
|
147
|
+
attached: menuPosition.attached,
|
|
148
|
+
borderless: getDataValue('menuBorderless'),
|
|
149
|
+
color: getDataValue('menuColor'),
|
|
150
|
+
compact: getDataValue('menuCompact'),
|
|
151
|
+
fluid: getDataValue('menuFluid'),
|
|
152
|
+
inverted: getDataValue('menuInverted'),
|
|
153
|
+
pointing: getDataValue('menuPointing'),
|
|
154
|
+
secondary: getDataValue('menuSecondary'),
|
|
155
|
+
size: getDataValue('menuSize'),
|
|
156
|
+
stackable: getDataValue('menuStackable'),
|
|
157
|
+
tabular: getDataValue('menuTabular'),
|
|
158
|
+
text: getDataValue('menuText'),
|
|
159
|
+
vertical: menuPosition.vertical,
|
|
160
|
+
className: cx(data.menuAlign, { container: isContainer }),
|
|
122
161
|
}}
|
|
162
|
+
menuPosition={menuPosition.direction}
|
|
123
163
|
panes={panes}
|
|
164
|
+
grid={{ paneWidth: 9, tabWidth: 3 }}
|
|
124
165
|
/>
|
|
125
166
|
</>
|
|
126
167
|
);
|