@eeacms/volto-tabs-block 1.3.2 → 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,24 @@ 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
+
7
20
  #### [1.3.2](https://github.com/eea/volto-tabs-block/compare/1.3.1...1.3.2)
8
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)
9
25
  - fix(edit): Align inner blocks toolbar CSS with columns/accordion/group block [`b51fe35`](https://github.com/eea/volto-tabs-block/commit/b51fe3591a6dddbca95f10deb20cf01390de742d)
10
26
 
11
27
  #### [1.3.1](https://github.com/eea/volto-tabs-block/compare/1.3.0...1.3.1)
@@ -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.2",
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
+ });
@@ -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,
@@ -120,4 +120,142 @@
120
120
  }
121
121
  }
122
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
+
123
261
  .loadAddonOverrides();
@@ -15,3 +15,6 @@
15
15
 
16
16
  /* Menu item */
17
17
  @menuItemCountDisplay: none;
18
+
19
+ @accordionMenuItemBackground: #F3F4F5;
20
+ @accordionTabBackground: transparent;