@eeacms/volto-tabs-block 1.3.0 → 2.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.
@@ -2,7 +2,11 @@ const defaultBabel = require('@plone/volto/babel');
2
2
 
3
3
  function applyDefault(api) {
4
4
  const voltoBabel = defaultBabel(api);
5
- voltoBabel.plugins.push('@babel/plugin-transform-modules-commonjs', 'transform-class-properties', 'istanbul');
5
+ voltoBabel.plugins.push(
6
+ '@babel/plugin-transform-modules-commonjs',
7
+ 'transform-class-properties',
8
+ 'istanbul',
9
+ );
6
10
  return voltoBabel;
7
11
  }
8
12
 
@@ -0,0 +1,46 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const projectRootPath = fs.realpathSync('./project'); // __dirname
5
+ const packageJson = require(path.join(projectRootPath, 'package.json'));
6
+ const jsConfig = require(path.join(projectRootPath, 'jsconfig.json')).compilerOptions;
7
+
8
+ const pathsConfig = jsConfig.paths;
9
+
10
+ let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
11
+
12
+ Object.keys(pathsConfig).forEach(pkg => {
13
+ if (pkg === '@plone/volto') {
14
+ voltoPath = `./${jsConfig.baseUrl}/${pathsConfig[pkg][0]}`;
15
+ }
16
+ });
17
+ const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
18
+ const reg = new AddonConfigurationRegistry(projectRootPath);
19
+
20
+ // Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
21
+ const addonAliases = Object.keys(reg.packages).map(o => [
22
+ o,
23
+ reg.packages[o].modulePath,
24
+ ]);
25
+
26
+
27
+ module.exports = {
28
+ extends: `${projectRootPath}/node_modules/@plone/volto/.eslintrc`,
29
+ settings: {
30
+ 'import/resolver': {
31
+ alias: {
32
+ map: [
33
+ ['@plone/volto', '@plone/volto/src'],
34
+ ...addonAliases,
35
+ ['@package', `${__dirname}/src`],
36
+ ['~', `${__dirname}/src`],
37
+ ],
38
+ extensions: ['.js', '.jsx', '.json'],
39
+ },
40
+ 'babel-plugin-root-import': {
41
+ rootPathSuffix: 'src',
42
+ },
43
+ },
44
+ },
45
+ };
46
+
package/CHANGELOG.md CHANGED
@@ -4,8 +4,37 @@ 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
+ #### [2.0.0](https://github.com/eea/volto-tabs-block/compare/1.3.2...2.0.0)
8
+
9
+ - Update [`525551e`](https://github.com/eea/volto-tabs-block/commit/525551e151d469f71e3ecbae9af994cf1dc61644)
10
+ - Improve accordion variation [`e95977e`](https://github.com/eea/volto-tabs-block/commit/e95977e2b06178dd820ea1b1983d74b4fd3f38f5)
11
+ - Release 2.0.0 [`1206ab1`](https://github.com/eea/volto-tabs-block/commit/1206ab1c22346761aacb9c5aba7c536e7407526e)
12
+ - Update accordion template title [`4b8def3`](https://github.com/eea/volto-tabs-block/commit/4b8def34c9a55e4b38cafb9b8533679a9759f5c5)
13
+ - stylelint [`13ef886`](https://github.com/eea/volto-tabs-block/commit/13ef886b203ad4f701820ae8d4066d87814a928f)
14
+ - stylelint [`d29ff73`](https://github.com/eea/volto-tabs-block/commit/d29ff739e17fe398373c289b01f57328543e333d)
15
+ - stylelint [`73195f6`](https://github.com/eea/volto-tabs-block/commit/73195f60362fffe12ae13f685a9c349cbe486118)
16
+ - prettier [`8308f52`](https://github.com/eea/volto-tabs-block/commit/8308f52c296f39da416c927d807f33741ecf66aa)
17
+ - Add accordion template for mobile [`92e99cf`](https://github.com/eea/volto-tabs-block/commit/92e99cf538983164426ad82b0e71e5ba6532e419)
18
+ - Remove useless from block title [`4ab8b58`](https://github.com/eea/volto-tabs-block/commit/4ab8b58b9266d2937fd033865e52100f0a6333b2)
19
+
20
+ #### [1.3.2](https://github.com/eea/volto-tabs-block/compare/1.3.1...1.3.2)
21
+
22
+ > 3 June 2022
23
+
24
+ - fix(edit): Align inner blocks toolbar CSS with columns/accordion/grou… [`#22`](https://github.com/eea/volto-tabs-block/pull/22)
25
+ - fix(edit): Align inner blocks toolbar CSS with columns/accordion/group block [`b51fe35`](https://github.com/eea/volto-tabs-block/commit/b51fe3591a6dddbca95f10deb20cf01390de742d)
26
+
27
+ #### [1.3.1](https://github.com/eea/volto-tabs-block/compare/1.3.0...1.3.1)
28
+
29
+ > 29 April 2022
30
+
31
+ - Style fix + missing key [`#21`](https://github.com/eea/volto-tabs-block/pull/21)
32
+
7
33
  #### [1.3.0](https://github.com/eea/volto-tabs-block/compare/1.2.12...1.3.0)
8
34
 
35
+ > 6 April 2022
36
+
37
+ - Refactor tabs block [`#19`](https://github.com/eea/volto-tabs-block/pull/19)
9
38
  - Refactor tabs block [`#18`](https://github.com/eea/volto-tabs-block/pull/18)
10
39
  - Fix tests [`fdc74d9`](https://github.com/eea/volto-tabs-block/commit/fdc74d9f5f1c851de9ca3a9576cf2dbcd1495968)
11
40
  - Bump version [`acfef41`](https://github.com/eea/volto-tabs-block/commit/acfef413eb9f923f7a7283d12417e23c81192633)
package/Jenkinsfile CHANGED
@@ -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 'NodeJS11';
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=$PATH:${scannerHome}/bin:${nodeJS}/bin; 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"
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
  }
@@ -0,0 +1,17 @@
1
+ module.exports = function (api) {
2
+ api.cache(true);
3
+ const presets = ['razzle/babel'];
4
+ const plugins = [
5
+ [
6
+ 'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work
7
+ {
8
+ messagesDir: './build/messages/',
9
+ },
10
+ ],
11
+ ];
12
+
13
+ return {
14
+ plugins,
15
+ presets,
16
+ };
17
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-tabs-block",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "volto-tabs-block: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -20,9 +20,10 @@
20
20
  "@eeacms/volto-block-style"
21
21
  ],
22
22
  "dependencies": {
23
+ "@eeacms/volto-block-style": "*",
24
+ "react-responsive-tabs": "4.4.3",
23
25
  "react-slick": "^0.24.0",
24
- "slick-carousel": "^1.8.1",
25
- "@eeacms/volto-block-style": "*"
26
+ "slick-carousel": "^1.8.1"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@cypress/code-coverage": "^3.9.5",
@@ -30,21 +31,19 @@
30
31
  },
31
32
  "scripts": {
32
33
  "release": "release-it",
33
- "release-major-beta": "release-it major --preRelease=beta",
34
- "release-beta": "release-it --preRelease=beta",
35
34
  "bootstrap": "npm install -g ejs; npm link ejs; node bootstrap",
36
35
  "test": "make test",
37
36
  "test:fix": "make test-update",
38
- "i18n": "rm -rf build/messages && NODE_ENV=production node src/i18n.js",
39
37
  "pre-commit": "yarn stylelint:fix && yarn prettier:fix && yarn lint:fix",
40
- "stylelint": "if [ -d ./project ]; then ./project/node_modules/stylelint/bin/stylelint.js --allow-empty-input 'src/**/*.{css,less}'; else ../../../node_modules/stylelint/bin/stylelint.js --allow-empty-input 'src/**/*.{css,less}'; fi",
41
- "stylelint:overrides": "if [ -d ./project ]; then ./project/node_modules/.bin/stylelint --syntax less --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides'; else ../../../node_modules/.bin/stylelint --syntax less --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides'; fi",
38
+ "stylelint": "../../../node_modules/.bin/stylelint 'theme/**/*.{css,less}' 'src/**/*.{css,less}'",
39
+ "stylelint:overrides": "../../../node_modules/.bin/stylelint --allow-empty-input 'theme/**/*.overrides' 'src/**/*.overrides'",
42
40
  "stylelint:fix": "yarn stylelint --fix && yarn stylelint:overrides --fix",
43
41
  "prettier": "if [ -d ./project ]; then ./project/node_modules/.bin/prettier --single-quote --check 'src/**/*.{js,jsx,json,css,less,md}'; else ../../../node_modules/.bin/prettier --single-quote --check 'src/**/*.{js,jsx,json,css,less,md}'; fi",
44
42
  "prettier:fix": "if [ -d ./project ]; then ./project/node_modules/.bin/prettier --single-quote --write 'src/**/*.{js,jsx,json,css,less,md}'; else ../../../node_modules/.bin/prettier --single-quote --write 'src/**/*.{js,jsx,json,css,less,md}'; fi",
45
43
  "lint": "if [ -d ./project ]; then ./project/node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}'; else ../../../node_modules/eslint/bin/eslint.js --max-warnings=0 'src/**/*.{js,jsx}'; fi",
46
44
  "lint:fix": "if [ -d ./project ]; then ./project/node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'; else ../../../node_modules/eslint/bin/eslint.js --fix 'src/**/*.{js,jsx}'; fi",
47
- "cypress:run": "if [ -d ./project ]; then ./project/node_modules/cypress/bin/cypress run; else ../../../node_modules/cypress/bin/cypress run; fi",
48
- "cypress:open": "if [ -d ./project ]; then ./project/node_modules/cypress/bin/cypress open; else ../../../node_modules/cypress/bin/cypress open; fi"
45
+ "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon",
46
+ "cypress:run": "if [ -d ./project ]; then NODE_ENV=development ./project/node_modules/cypress/bin/cypress run; else NODE_ENV=development ../../../node_modules/cypress/bin/cypress run; fi",
47
+ "cypress:open": "if [ -d ./project ]; then NODE_ENV=development ./project/node_modules/cypress/bin/cypress open; else NODE_ENV=development ../../../node_modules/cypress/bin/cypress open; fi"
49
48
  }
50
49
  }
@@ -7,5 +7,6 @@ export { TabsEdit, TabsView };
7
7
  export { layoutSchema };
8
8
 
9
9
  export * from './templates/default';
10
+ export * from './templates/accordion';
10
11
  export * from './templates/horizontal-responsive';
11
12
  export * from './templates/carousel';
@@ -0,0 +1,18 @@
1
+ import { DefaultEdit } from '../default';
2
+
3
+ const Edit = (props) => {
4
+ return (
5
+ <DefaultEdit
6
+ {...props}
7
+ data={{
8
+ ...props.data,
9
+ menuPointing: true,
10
+ menuSecondary: true,
11
+ menuFluid: false,
12
+ menuText: false,
13
+ }}
14
+ />
15
+ );
16
+ };
17
+
18
+ export default Edit;
@@ -0,0 +1,125 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { compose } from 'redux';
4
+ import { withRouter } from 'react-router';
5
+ import Tabs from 'react-responsive-tabs';
6
+ import AnimateHeight from 'react-animate-height';
7
+ import { Icon } from 'semantic-ui-react';
8
+ import config from '@plone/volto/registry';
9
+ import { Icon as VoltoIcon, RenderBlocks } from '@plone/volto/components';
10
+ import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
11
+ import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
12
+
13
+ import 'react-responsive-tabs/styles.css';
14
+ import '@eeacms/volto-tabs-block/less/menu.less';
15
+
16
+ class Tab extends React.Component {
17
+ constructor() {
18
+ super();
19
+ this.state = {
20
+ height: 0,
21
+ };
22
+ }
23
+
24
+ componentDidMount() {
25
+ if (this.state.height === 0) {
26
+ requestAnimationFrame(() => {
27
+ this.setState({ height: 'auto' });
28
+ });
29
+ }
30
+ }
31
+
32
+ render() {
33
+ return (
34
+ <AnimateHeight animateOpacity duration={500} height={this.state.height}>
35
+ <RenderBlocks {...this.props} />
36
+ </AnimateHeight>
37
+ );
38
+ }
39
+ }
40
+
41
+ const View = (props) => {
42
+ const {
43
+ data = {},
44
+ tabsList = [],
45
+ tabs = {},
46
+ activeTabIndex = 0,
47
+ setActiveTab = () => {},
48
+ } = props;
49
+ const accordionConfig =
50
+ config.blocks.blocksConfig.tabs_block.templates.accordion;
51
+ const { icons, semanticIcon } = accordionConfig;
52
+
53
+ const schema = React.useMemo(
54
+ () =>
55
+ config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
56
+ config,
57
+ props,
58
+ ) || {},
59
+ [props],
60
+ );
61
+
62
+ const getDataValue = React.useCallback(
63
+ (key) => {
64
+ return (
65
+ (schema.properties[key]?.value || data[key]) ??
66
+ schema.properties[key]?.defaultValue
67
+ );
68
+ },
69
+ [schema, data],
70
+ );
71
+
72
+ const items = tabsList.map((tab, index) => {
73
+ const title = tabs[tab].title;
74
+ const defaultTitle = `Tab ${index + 1}`;
75
+ const active = activeTabIndex === index;
76
+ return {
77
+ title: (
78
+ <>
79
+ {semanticIcon ? (
80
+ <Icon name={active ? semanticIcon.opened : semanticIcon.closed} />
81
+ ) : (
82
+ <VoltoIcon
83
+ name={active ? icons.opened : icons.closed}
84
+ size={icons.size}
85
+ />
86
+ )}
87
+ {title || defaultTitle}{' '}
88
+ </>
89
+ ),
90
+ getContent: () => <Tab {...props} tab={tab} content={tabs[tab]} />,
91
+ key: tab,
92
+ tabClassName: cx('ui button item title', { active }),
93
+ panelClassName: cx('ui bottom attached segment tab', {
94
+ active,
95
+ }),
96
+ };
97
+ });
98
+
99
+ return (
100
+ <>
101
+ <Tabs
102
+ className="tabs aa"
103
+ selectedTabKey={tabsList[activeTabIndex]}
104
+ items={items}
105
+ onChange={(tab) => {
106
+ if (tab !== tabsList[activeTabIndex]) {
107
+ setActiveTab(tab);
108
+ } else {
109
+ setActiveTab(null);
110
+ }
111
+ }}
112
+ tabsWrapperClass={cx(
113
+ 'ui pointing secondary menu',
114
+ getDataValue('menuColor'),
115
+ {
116
+ inverted: getDataValue('menuInverted'),
117
+ },
118
+ )}
119
+ showMore={false}
120
+ />
121
+ </>
122
+ );
123
+ };
124
+
125
+ export default compose(withScrollToTarget, withRouter)(View);
@@ -0,0 +1,5 @@
1
+ import AccordionEdit from './Edit';
2
+ import AccordionView from './View';
3
+ import accordionSchema from './schema';
4
+
5
+ export { AccordionEdit, AccordionView, accordionSchema };
@@ -0,0 +1,44 @@
1
+ export default () => ({
2
+ title: 'Accordion tabs block',
3
+ fieldsets: [
4
+ {
5
+ id: 'default',
6
+ title: 'Default',
7
+ fields: ['description'],
8
+ },
9
+ {
10
+ id: 'menu',
11
+ title: 'Menu',
12
+ fields: ['menuColor', 'menuInverted'],
13
+ },
14
+ ],
15
+ properties: {
16
+ description: {
17
+ title: 'Description',
18
+ },
19
+ menuColor: {
20
+ title: 'Color',
21
+ defaultValue: 'green',
22
+ choices: [
23
+ ['red', 'Red'],
24
+ ['orange', 'Orange'],
25
+ ['yellow', 'Yellow'],
26
+ ['olive', 'Olive'],
27
+ ['green', 'Green'],
28
+ ['teal', 'Teal'],
29
+ ['blue', 'Blue'],
30
+ ['violet', 'Violet'],
31
+ ['purple', 'Purple'],
32
+ ['pink', 'Pink'],
33
+ ['brown', 'Brown'],
34
+ ['grey', 'Grey'],
35
+ ['black', 'Black'],
36
+ ],
37
+ },
38
+ menuInverted: {
39
+ title: 'Inverted',
40
+ type: 'boolean',
41
+ },
42
+ },
43
+ required: [],
44
+ });
@@ -121,6 +121,7 @@ const View = (props) => {
121
121
  menuItem: (
122
122
  <MenuItem
123
123
  {...props}
124
+ key={tab}
124
125
  tab={tab}
125
126
  index={index}
126
127
  tabsTitle={tabsTitle}
@@ -61,15 +61,16 @@ const MenuWrapper = (props) => {
61
61
  tabsList = [],
62
62
  setActiveTab = () => {},
63
63
  } = props;
64
+ const [open, setOpen] = React.useState(false);
64
65
 
65
66
  React.useEffect(() => {
66
67
  if (!true || !node?.current) return;
67
68
  const items = node.current.querySelectorAll(
68
69
  '.ui.menu > .menu-wrapper > .item:not(.menu-title)',
69
70
  );
70
- const underlineMenu = node.current.querySelector('.ui.dropdown');
71
- if (!underlineMenu) return;
72
- const overflowOffset = positionedOffset(underlineMenu, node.current);
71
+ const underlineDropdown = node.current.querySelector('.ui.dropdown');
72
+ if (!underlineDropdown) return;
73
+ const overflowOffset = positionedOffset(underlineDropdown, node.current);
73
74
  if (!overflowOffset) {
74
75
  return;
75
76
  }
@@ -83,8 +84,11 @@ const MenuWrapper = (props) => {
83
84
  anyHidden = anyHidden || hidden;
84
85
  }
85
86
  }
86
- underlineMenu.style.visibility = anyHidden ? '' : 'hidden';
87
- }, [screen, node, data.isResponsive]);
87
+ underlineDropdown.style.visibility = anyHidden ? '' : 'hidden';
88
+ if (!anyHidden && open) {
89
+ setOpen(false);
90
+ }
91
+ }, [screen, node, open, data.isResponsive]);
88
92
 
89
93
  return (
90
94
  <React.Fragment>
@@ -95,39 +99,38 @@ const MenuWrapper = (props) => {
95
99
  </React.Fragment>
96
100
  ))}
97
101
  </div>
98
- {true && (
99
- <Dropdown
100
- icon="ellipsis horizontal"
101
- className="item"
102
- pointing="top right"
103
- >
104
- <Dropdown.Menu>
105
- {tabsList.map((underlineTab, underlineIndex) => {
106
- const title = tabs[underlineTab].title;
107
- const defaultTitle = `Tab ${underlineIndex + 1}`;
102
+ <Dropdown
103
+ icon="ellipsis horizontal"
104
+ className="item"
105
+ pointing="top right"
106
+ open={open}
107
+ onOpen={() => setOpen(true)}
108
+ onClose={() => setOpen(false)}
109
+ >
110
+ <Dropdown.Menu>
111
+ {tabsList.map((underlineTab, underlineIndex) => {
112
+ const title = tabs[underlineTab].title;
113
+ const defaultTitle = `Tab ${underlineIndex + 1}`;
108
114
 
109
- return (
110
- <Dropdown.Item
111
- hidden
112
- key={`underline-tab-${underlineIndex}-${underlineTab}`}
113
- underline-item-data={underlineTab}
114
- active={underlineTab === activeTab}
115
- onClick={() => {
116
- if (activeTab !== underlineTab) {
117
- setActiveTab(underlineTab);
118
- }
119
- }}
120
- >
121
- <span className={'menu-item-count'}>
122
- {underlineIndex + 1}
123
- </span>
124
- <p className={'menu-item-text'}>{title || defaultTitle}</p>
125
- </Dropdown.Item>
126
- );
127
- })}
128
- </Dropdown.Menu>
129
- </Dropdown>
130
- )}
115
+ return (
116
+ <Dropdown.Item
117
+ hidden
118
+ key={`underline-tab-${underlineIndex}-${underlineTab}`}
119
+ underline-item-data={underlineTab}
120
+ active={underlineTab === activeTab}
121
+ onClick={() => {
122
+ if (activeTab !== underlineTab) {
123
+ setActiveTab(underlineTab);
124
+ }
125
+ }}
126
+ >
127
+ <span className={'menu-item-count'}>{underlineIndex + 1}</span>
128
+ <p className={'menu-item-text'}>{title || defaultTitle}</p>
129
+ </Dropdown.Item>
130
+ );
131
+ })}
132
+ </Dropdown.Menu>
133
+ </Dropdown>
131
134
  </React.Fragment>
132
135
  );
133
136
  };
@@ -201,6 +204,7 @@ const View = (props) => {
201
204
  menuItem: (
202
205
  <MenuItem
203
206
  {...props}
207
+ key={tab}
204
208
  tab={tab}
205
209
  tabsList={tabsList}
206
210
  index={index}
@@ -245,7 +249,6 @@ const View = (props) => {
245
249
  text: getDataValue('menuText'),
246
250
  vertical: menuPosition.vertical,
247
251
  className: cx(data.menuAlign, { container: isContainer }),
248
- items: undefined,
249
252
  children: (
250
253
  <MenuWrapper
251
254
  {...props}
@@ -1,5 +1,5 @@
1
1
  export default () => ({
2
- title: 'Default tabs block',
2
+ title: 'Horizontal tabs block',
3
3
  fieldsets: [
4
4
  {
5
5
  id: 'default',
package/src/index.js CHANGED
@@ -2,10 +2,13 @@ import { TabsEdit, TabsView } from '@eeacms/volto-tabs-block/components';
2
2
  import {
3
3
  DefaultEdit,
4
4
  DefaultView,
5
+ AccordionEdit,
6
+ AccordionView,
5
7
  HorizontalResponsiveView,
6
8
  HorizontalCarouselView,
7
9
  VerticalCarouselView,
8
10
  defaultSchema,
11
+ accordionSchema,
9
12
  horizontalResponsiveSchema,
10
13
  carouselSchema,
11
14
  } from '@eeacms/volto-tabs-block/components';
@@ -14,11 +17,13 @@ import { TABS_BLOCK } from './constants';
14
17
  import { TabsWidget } from './widgets';
15
18
 
16
19
  import tabsSVG from '@eeacms/volto-tabs-block//icons/tabs.svg';
20
+ import rightSVG from '@plone/volto/icons/right-key.svg';
21
+ import downSVG from '@plone/volto/icons/down-key.svg';
17
22
 
18
23
  export default (config) => {
19
24
  config.blocks.blocksConfig[TABS_BLOCK] = {
20
25
  id: TABS_BLOCK,
21
- title: 'Tabs block',
26
+ title: 'Tabs',
22
27
  icon: tabsSVG,
23
28
  group: 'common',
24
29
  edit: TabsEdit,
@@ -39,6 +44,17 @@ export default (config) => {
39
44
  view: DefaultView,
40
45
  schema: defaultSchema,
41
46
  },
47
+ accordion: {
48
+ title: 'Accordion responsive',
49
+ edit: AccordionEdit,
50
+ view: AccordionView,
51
+ schema: accordionSchema,
52
+ icons: {
53
+ closed: rightSVG,
54
+ opened: downSVG,
55
+ size: '24px',
56
+ },
57
+ },
42
58
  'horizontal-responsive': {
43
59
  title: 'Horizontal responsive',
44
60
  edit: DefaultEdit,
@@ -1,3 +1,10 @@
1
+ @type: 'extra';
2
+ @element: 'custom';
3
+
4
+ @import (multiple, reference, optional) '../../theme.config';
5
+
6
+ @borderColor: rgba(120, 192, 215, 0.75);
7
+
1
8
  .inner.tabs_block {
2
9
  margin-bottom: 0;
3
10
 
@@ -68,48 +75,36 @@
68
75
  }
69
76
  }
70
77
 
78
+ .blocks-form {
79
+ margin-top: 0.5rem;
80
+ }
81
+
82
+ .blocks-chooser {
83
+ right: 0;
84
+ left: auto;
85
+ margin-top: 3rem;
86
+ }
87
+
71
88
  .block-toolbar {
72
89
  position: absolute;
73
90
  z-index: 3;
74
- right: unset;
75
- left: -9px;
91
+ right: -9px;
76
92
  display: flex;
77
- padding: 5px;
78
- border: 1px solid #78c0d7bf;
79
- border-bottom: 1px solid #fff;
93
+ border: none;
94
+ border: 1px solid @borderColor;
95
+ border-bottom: 1px solid @pageBackground;
80
96
  margin-top: -45px;
81
- background-color: #fff;
97
+ background-color: @pageBackground;
82
98
  border-top-left-radius: 1rem;
83
99
  border-top-right-radius: 1rem;
84
100
 
85
101
  .ui.basic.button {
86
- padding: 3px;
87
- padding-right: 0;
88
- box-shadow: none;
102
+ padding: 8px 5px;
89
103
  }
90
104
 
91
- .wrapper-column-block {
92
- > .ui.basic.button {
93
- &:hover {
94
- background-color: transparent !important;
95
- }
96
- }
105
+ .ui.basic.button:hover {
106
+ background: transparent !important;
97
107
  }
98
-
99
- > .ui.basic.button {
100
- &:hover {
101
- background-color: transparent !important;
102
- }
103
-
104
- svg {
105
- color: #134448;
106
- }
107
- }
108
- }
109
-
110
- .blocks-chooser {
111
- left: 0;
112
- margin-top: 50px;
113
108
  }
114
109
  }
115
110
 
@@ -86,6 +86,7 @@
86
86
 
87
87
  &.horizontal-responsive {
88
88
  .horizontal-responsive.tabs > .ui.menu {
89
+ overflow: visible;
89
90
  justify-content: space-between;
90
91
 
91
92
  .menu-wrapper {
@@ -119,4 +120,142 @@
119
120
  }
120
121
  }
121
122
 
123
+ .ui.menu:not(.RRT__accordion) {
124
+ .ui.item .icon {
125
+ display: none;
126
+ }
127
+ }
128
+
129
+ .RRT__container {
130
+ > .ui.tab .rah-animating {
131
+ transition: height 0ms ease 0ms !important;
132
+
133
+ > div {
134
+ transition: opacity 0ms ease 0ms !important;
135
+ }
136
+ }
137
+ }
138
+
139
+ .ui.menu.RRT__accordion {
140
+ &::before {
141
+ display: none;
142
+ }
143
+
144
+ border-bottom: none !important;
145
+
146
+ .ui.item {
147
+ display: flex;
148
+ width: 100%;
149
+ padding: 0.75rem 1rem !important;
150
+ border-width: 0 !important;
151
+ border-bottom: none !important;
152
+ margin: 0 !important;
153
+ background-color: @accordionMenuItemBackground;
154
+
155
+ .icon {
156
+ margin: 0 !important;
157
+ }
158
+
159
+ .dropdown.icon {
160
+ transform: rotate(-90deg);
161
+ }
162
+
163
+ &.active {
164
+ .dropdown.icon {
165
+ transform: rotate(0);
166
+ }
167
+ }
168
+ }
169
+
170
+ &.red {
171
+ .ui.item.active {
172
+ background-color: @red !important;
173
+ color: #fff !important;
174
+ }
175
+ }
176
+
177
+ &.orange {
178
+ .ui.item.active {
179
+ background-color: @orange !important;
180
+ color: #fff !important;
181
+ }
182
+ }
183
+
184
+ &.yellow {
185
+ .ui.item.active {
186
+ background-color: @yellow !important;
187
+ color: #fff !important;
188
+ }
189
+ }
190
+
191
+ &.olive {
192
+ .ui.item.active {
193
+ background-color: @olive !important;
194
+ color: #fff !important;
195
+ }
196
+ }
197
+
198
+ &.green {
199
+ .ui.item.active {
200
+ background-color: @green !important;
201
+ color: #fff !important;
202
+ }
203
+ }
204
+
205
+ &.teal {
206
+ .ui.item.active {
207
+ background-color: @teal !important;
208
+ color: #fff !important;
209
+ }
210
+ }
211
+
212
+ &.blue {
213
+ .ui.item.active {
214
+ background-color: @blue !important;
215
+ color: #fff !important;
216
+ }
217
+ }
218
+
219
+ &.violet {
220
+ .ui.item.active {
221
+ background-color: @violet !important;
222
+ color: #fff !important;
223
+ }
224
+ }
225
+
226
+ &.purple {
227
+ .ui.item.active {
228
+ background-color: @purple !important;
229
+ color: #fff !important;
230
+ }
231
+ }
232
+
233
+ &.brown {
234
+ .ui.item.active {
235
+ background-color: @brown !important;
236
+ color: #fff !important;
237
+ }
238
+ }
239
+
240
+ &.grey {
241
+ .ui.item.active {
242
+ background-color: @grey !important;
243
+ color: #fff !important;
244
+ }
245
+ }
246
+
247
+ &.black {
248
+ .ui.item.active {
249
+ background-color: @black !important;
250
+ color: #fff !important;
251
+ }
252
+ }
253
+
254
+ .ui.tab {
255
+ padding: 1rem;
256
+ margin-bottom: 0;
257
+ background-color: @accordionTabBackground !important;
258
+ }
259
+ }
260
+
122
261
  .loadAddonOverrides();
@@ -15,3 +15,6 @@
15
15
 
16
16
  /* Menu item */
17
17
  @menuItemCountDisplay: none;
18
+
19
+ @accordionMenuItemBackground: #F3F4F5;
20
+ @accordionTabBackground: transparent;