@eeacms/volto-tabs-block 6.0.3 → 7.0.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +115 -3
  2. package/README.md +17 -0
  3. package/cypress.config.js +2 -2
  4. package/locales/de/LC_MESSAGES/volto.po +76 -29
  5. package/locales/en/LC_MESSAGES/volto.po +76 -29
  6. package/locales/es/LC_MESSAGES/volto.po +77 -30
  7. package/locales/it/LC_MESSAGES/volto.po +76 -29
  8. package/locales/pt_BR/LC_MESSAGES/volto.po +77 -30
  9. package/locales/ro/LC_MESSAGES/volto.po +76 -29
  10. package/locales/volto.pot +77 -30
  11. package/package.json +1 -1
  12. package/src/components/Edit.jsx +119 -102
  13. package/src/components/View.jsx +6 -4
  14. package/src/components/index.js +1 -0
  15. package/src/components/layoutSchema.js +3 -1
  16. package/src/components/schema.js +169 -70
  17. package/src/components/templates/accordion/Edit.jsx +28 -199
  18. package/src/components/templates/accordion/View.jsx +42 -64
  19. package/src/components/templates/accordion/index.js +1 -2
  20. package/src/components/templates/accordion/schema.js +33 -40
  21. package/src/components/templates/carousel/HorizontalView.jsx +3 -0
  22. package/src/components/templates/carousel/VerticalView.jsx +3 -0
  23. package/src/components/templates/carousel/index.js +1 -2
  24. package/src/components/templates/carousel/schema.js +19 -25
  25. package/src/components/templates/default/Edit.jsx +90 -50
  26. package/src/components/templates/default/View.jsx +112 -42
  27. package/src/components/templates/default/index.js +2 -2
  28. package/src/components/templates/default/schema.js +69 -77
  29. package/src/components/templates/horizontal-responsive/Edit.jsx +63 -46
  30. package/src/components/templates/horizontal-responsive/View.jsx +33 -37
  31. package/src/components/templates/horizontal-responsive/index.js +1 -6
  32. package/src/components/templates/horizontal-responsive/schema.js +6 -5
  33. package/src/helpers.js +14 -10
  34. package/src/helpers.test.js +14 -8
  35. package/src/index.js +34 -22
  36. package/src/less/carousel.less +9 -0
  37. package/src/less/edit.less +26 -0
  38. package/src/less/menu.less +118 -4
  39. package/src/less/menu.variables +16 -0
  40. package/src/less/tabs.less +53 -23
  41. package/src/less/tabs.variables +3 -0
  42. package/src/widgets/TabsWidget.jsx +158 -68
@@ -1,183 +1,29 @@
1
1
  import React from 'react';
2
2
  import cx from 'classnames';
3
- import { compose } from 'redux';
4
3
  import { isEmpty } from 'lodash';
5
- import { v4 as uuid } from 'uuid';
6
- import { withRouter } from 'react-router';
4
+ import { useIntl } from 'react-intl';
7
5
  import Tabs from 'react-responsive-tabs';
8
- import AnimateHeight from 'react-animate-height';
9
6
  import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
7
+ import { MenuItem } from '@eeacms/volto-tabs-block/components/templates/default/Edit';
10
8
  import { emptyBlocksForm } from '@plone/volto/helpers';
11
- import { Menu, Input, Icon } from 'semantic-ui-react';
9
+ import { Icon } from 'semantic-ui-react';
12
10
  import { Icon as VoltoIcon, BlocksForm } from '@plone/volto/components';
13
11
  import config from '@plone/volto/registry';
14
12
  import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
15
- import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
16
13
  import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
17
14
  import noop from 'lodash/noop';
18
- import '@eeacms/volto-tabs-block/less/menu.less';
19
15
 
20
- const MenuItem = (props) => {
21
- const inputRef = React.useRef(null);
22
- const {
23
- activeTab = null,
24
- activeBlock = null,
25
- block = null,
26
- data = {},
27
- editingTab = null,
28
- selected = false,
29
- tabData = {},
30
- tabs = {},
31
-
32
- tabsData = {},
33
- tabsDescription,
34
- tabsList = [],
35
- tabsTitle,
36
- emptyTab = noop,
37
- setActiveBlock = noop,
38
- setActiveTab = noop,
39
- setEditingTab = noop,
40
- onChangeBlock = noop,
41
- } = props;
42
- const { tab, index } = props;
43
- const tabIndex = index + 1;
44
- const defaultTitle = `Tab ${tabIndex}`;
45
- const title = tabs[tab]?.title;
46
- const addNewTab = () => {
47
- const tabId = uuid();
48
-
49
- onChangeBlock(block, {
50
- ...data,
51
- data: {
52
- ...tabsData,
53
- blocks: {
54
- ...tabsData.blocks,
55
- [tabId]: {
56
- ...emptyTab(),
57
- },
58
- },
59
- blocks_layout: {
60
- items: [...tabsData.blocks_layout.items, tabId],
61
- },
62
- },
63
- });
64
- };
65
-
66
- React.useEffect(() => {
67
- if (editingTab === tab && inputRef.current) {
68
- inputRef.current.focus();
69
- }
70
- /* eslint-disable-next-line */
71
- }, [editingTab]);
72
-
73
- return (
74
- <>
75
- {index === 0 && (tabsTitle || tabsDescription) && (
76
- <div className="menu-title"></div>
77
- )}
78
-
79
- <Menu.Item
80
- role="tab"
81
- aria-hidden="true"
82
- name={defaultTitle}
83
- active={tab === activeTab}
84
- onClick={() => {
85
- if (activeTab !== tab) {
86
- setActiveTab(tab);
87
- }
88
- if (activeBlock) {
89
- setActiveBlock(null);
90
- }
91
- if (editingTab !== tab) {
92
- setEditingTab(null);
93
- }
94
- }}
95
- onDoubleClick={() => {
96
- setEditingTab(tab);
97
- }}
98
- className="remove-margin"
99
- >
100
- {editingTab === tab && selected ? (
101
- <Input
102
- placeholder={defaultTitle}
103
- ref={inputRef}
104
- transparent
105
- value={title}
106
- onChange={(e) => {
107
- onChangeBlock(block, {
108
- ...data,
109
- data: {
110
- ...tabsData,
111
- blocks: {
112
- ...tabsData.blocks,
113
- [tab]: {
114
- ...(tabData || {}),
115
- title: e.target.value,
116
- },
117
- },
118
- },
119
- });
120
- }}
121
- />
122
- ) : (
123
- <>
124
- <p className={'menu-item-text'}>{title || defaultTitle}</p>
125
- </>
126
- )}
127
- </Menu.Item>
128
- {index === tabsList.length - 1 ? (
129
- <>
130
- <Menu.Item
131
- role="tab"
132
- aria-hidden="true"
133
- name="addition"
134
- onClick={() => {
135
- addNewTab();
136
- setEditingTab(null);
137
- }}
138
- className="remove-margin addition-button"
139
- >
140
- <p className={'menu-item-text'}>+</p>
141
- </Menu.Item>
142
- </>
143
- ) : (
144
- ''
145
- )}
146
- </>
147
- );
148
- };
16
+ import '@eeacms/volto-tabs-block/less/menu.less';
17
+ import { accordionSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/accordion/schema';
149
18
 
150
19
  class Tab extends React.Component {
151
- constructor() {
152
- super();
153
- this.state = {
154
- height: 0,
155
- };
156
- }
157
-
158
- componentDidMount() {
159
- if (this.state.height === 0) {
160
- requestAnimationFrame(() => {
161
- this.setState({ height: 'auto' });
162
- });
163
- }
164
- }
165
-
166
20
  render() {
167
- return (
168
- <AnimateHeight
169
- animateOpacity
170
- duration={500}
171
- height={this.state.height}
172
- aria-hidden={false}
173
- >
174
- {this.props.children}
175
- </AnimateHeight>
176
- );
21
+ return this.props.children;
177
22
  }
178
23
  }
179
24
 
180
25
  const Edit = (props) => {
26
+ const intl = useIntl();
181
27
  const {
182
28
  data = {},
183
29
  tabsList = [],
@@ -198,41 +44,22 @@ const Edit = (props) => {
198
44
  onSelectBlock = noop,
199
45
  emptyTab = noop,
200
46
  tabsData = {},
47
+ schema,
201
48
  } = props;
202
49
 
203
- const accordionConfig =
204
- config.blocks.blocksConfig[TABS_BLOCK].templates?.['accordion'] || {};
205
- const { icons, semanticIcon, transformWidth = 800 } = accordionConfig;
50
+ const { menuInverted, menuSecondary, menuPointing } = data;
51
+ const accordionConfig = config.blocks.blocksConfig[
52
+ TABS_BLOCK
53
+ ].variations.filter((v, _i) => v.id === data.variation);
54
+ const { icons, semanticIcon, transformWidth = 800 } = accordionConfig?.[0];
206
55
 
207
56
  const tabsContainer = React.useRef();
208
57
  const [mounted, setMounted] = React.useState(false);
209
58
  const [hashTab, setHashTab] = React.useState(false);
210
59
  const [initialWidth, setInitialWidth] = React.useState(transformWidth);
211
60
 
212
- const schema = React.useMemo(
213
- () =>
214
- config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
215
- config,
216
- props,
217
- ) || {},
218
- [props],
219
- );
220
-
221
- const getDataValue = React.useCallback(
222
- (key) => {
223
- return (
224
- (schema.properties[key]?.value || data[key]) ??
225
- schema.properties[key]?.defaultValue
226
- );
227
- },
228
- [schema, data],
229
- );
230
-
231
61
  const items = tabsList.map((tab, index) => {
232
- const title = tabs[tab]?.title;
233
- const defaultTitle = `Tab ${index + 1}`;
234
62
  const active = activeTabIndex === index;
235
- const tabsDescription = data.description;
236
63
 
237
64
  return {
238
65
  title: (
@@ -259,8 +86,7 @@ const Edit = (props) => {
259
86
  index={index}
260
87
  setEditingTab={setEditingTab}
261
88
  tab={tab}
262
- tabsTitle={title || defaultTitle}
263
- tabsDescription={tabsDescription}
89
+ schema={schema}
264
90
  />
265
91
  </>
266
92
  ),
@@ -268,7 +94,7 @@ const Edit = (props) => {
268
94
  <Tab {...props} tab={tab} content={tabs[tab]} aria-hidden={false}>
269
95
  <BlocksForm
270
96
  allowedBlocks={data?.allowedBlocks}
271
- description={data?.instrunctions?.data}
97
+ description={data?.instructions?.data}
272
98
  manage={manage}
273
99
  metadata={metadata}
274
100
  pathname={props.pathname}
@@ -289,7 +115,10 @@ const Edit = (props) => {
289
115
  [activeTab]: {
290
116
  ...(newFormData.blocks_layout.items.length > 0
291
117
  ? newFormData
292
- : emptyTab()),
118
+ : emptyTab({
119
+ schema: schema.properties.data.schema,
120
+ intl,
121
+ })),
293
122
  },
294
123
  },
295
124
  },
@@ -347,16 +176,14 @@ const Edit = (props) => {
347
176
  selectedTabKey={tabsList[activeTabIndex]}
348
177
  unmountOnExit={false}
349
178
  items={items}
350
- onChange={(tab) => {
179
+ onChange={() => {
351
180
  const { blockWidth } = tabsContainer.current?.state || {};
352
181
  const tabWithHash = getParentTabFromHash(
353
182
  data,
354
- props.location.hash.substring(1),
183
+ props?.location?.hash.substring(1),
355
184
  );
356
- if (tabWithHash === tabsList[activeTabIndex] && !hashTab)
185
+ if (tabWithHash === tabsList[activeTabIndex] && !hashTab) {
357
186
  setHashTab(true);
358
- else if (tab !== tabsList[activeTabIndex]) {
359
- setActiveTab(tab);
360
187
  } else if (blockWidth <= initialWidth) {
361
188
  setActiveTab(null);
362
189
  }
@@ -367,13 +194,13 @@ const Edit = (props) => {
367
194
  'tabs-accessibility',
368
195
  data?.theme ? `${data?.theme}` : '',
369
196
  {
370
- inverted: getDataValue('menuInverted'),
197
+ inverted: menuInverted,
371
198
  },
372
199
  {
373
- pointing: getDataValue('menuPointing'),
200
+ pointing: menuPointing,
374
201
  },
375
202
  {
376
- secondary: getDataValue('menuSecondary'),
203
+ secondary: menuSecondary,
377
204
  },
378
205
  )}
379
206
  showMore={false}
@@ -381,4 +208,6 @@ const Edit = (props) => {
381
208
  );
382
209
  };
383
210
 
384
- export default compose(withScrollToTarget, withRouter)(Edit);
211
+ Edit.schemaEnhancer = accordionSchemaEnhancer;
212
+
213
+ export default Edit;
@@ -1,52 +1,28 @@
1
1
  import React, { useLayoutEffect } from 'react';
2
- import cx from 'classnames';
3
2
  import { compose } from 'redux';
4
3
  import { withRouter } from 'react-router';
5
- import Tabs from 'react-responsive-tabs';
6
- import AnimateHeight from 'react-animate-height';
4
+ import { withResizeDetector } from 'react-resize-detector';
5
+ import cx from 'classnames';
6
+ import noop from 'lodash/noop';
7
+
7
8
  import { Icon } from 'semantic-ui-react';
9
+ import { Icon as VoltoIcon } from '@plone/volto/components';
10
+ import { RenderBlocks } from '@plone/volto/components';
8
11
  import config from '@plone/volto/registry';
9
- import { Icon as VoltoIcon, RenderBlocks } from '@plone/volto/components';
12
+
13
+ import Tabs from 'react-responsive-tabs';
14
+ import { AssetTab } from '@eeacms/volto-tabs-block/components';
10
15
  import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
11
- import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
12
16
  import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
13
- import noop from 'lodash/noop';
14
-
15
- import { withResizeDetector } from 'react-resize-detector';
17
+ import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
16
18
 
17
19
  import '@eeacms/volto-tabs-block/less/menu.less';
18
20
 
19
21
  class Tab extends React.Component {
20
- constructor() {
21
- super();
22
- this.animateId = null;
23
- this.state = {
24
- height: 0,
25
- };
26
- }
27
-
28
- componentDidMount() {
29
- if (this.state.height === 0) {
30
- this.animateId = requestAnimationFrame(() => {
31
- this.setState({ height: 'auto' });
32
- });
33
- }
34
- }
35
- componentWillUnmount() {
36
- cancelAnimationFrame(this.animateId);
37
- }
38
-
39
22
  render() {
40
23
  return (
41
24
  <div id={this.props.title} className="tab-name">
42
- <AnimateHeight
43
- animateOpacity
44
- duration={500}
45
- height={this.state.height}
46
- aria-hidden={false}
47
- >
48
- <RenderBlocks {...this.props} />
49
- </AnimateHeight>
25
+ <RenderBlocks {...this.props} />
50
26
  </div>
51
27
  );
52
28
  }
@@ -62,9 +38,11 @@ const View = (props) => {
62
38
  width,
63
39
  id,
64
40
  } = props;
65
- const accordionConfig =
66
- config.blocks.blocksConfig[TABS_BLOCK].templates?.['accordion'] || {};
67
- const { icons, semanticIcon, transformWidth = 800 } = accordionConfig;
41
+
42
+ const accordionConfig = config.blocks.blocksConfig[
43
+ TABS_BLOCK
44
+ ].variations.filter((v, _i) => v.id === data.variation);
45
+ const { icons, semanticIcon, transformWidth = 800 } = accordionConfig?.[0];
68
46
 
69
47
  const tabsContainer = React.useRef();
70
48
  const [mounted, setMounted] = React.useState(false);
@@ -75,29 +53,13 @@ const View = (props) => {
75
53
  tabs_width < initialWidth,
76
54
  );
77
55
 
78
- const schema = React.useMemo(
79
- () =>
80
- config.blocks.blocksConfig[TABS_BLOCK].templates?.['default']?.schema(
81
- config,
82
- props,
83
- ) || {},
84
- [props],
85
- );
86
-
87
- const getDataValue = React.useCallback(
88
- (key) => {
89
- return (
90
- (schema.properties[key]?.value || data[key]) ??
91
- schema.properties[key]?.defaultValue
92
- );
93
- },
94
- [schema, data],
95
- );
96
-
97
56
  const items = tabsList.map((tab, index) => {
98
- const title = tabs[tab].title;
99
57
  const defaultTitle = `Tab ${index + 1}`;
100
58
  const active = activeTabIndex === index;
59
+ const tabSettings = tabs[tab];
60
+ const { title, assetType } = tabSettings;
61
+ const tabIndex = index + 1;
62
+ const tabTitle = title || defaultTitle;
101
63
 
102
64
  return {
103
65
  title: (
@@ -112,7 +74,15 @@ const View = (props) => {
112
74
  size={icons.size}
113
75
  />
114
76
  )}
115
- <span>{title || defaultTitle} </span>
77
+ {assetType ? (
78
+ <AssetTab
79
+ props={tabSettings}
80
+ tabTitle={tabTitle}
81
+ tabIndex={tabIndex}
82
+ />
83
+ ) : (
84
+ <span>{title || defaultTitle}</span>
85
+ )}
116
86
  </>
117
87
  ),
118
88
  content: (
@@ -143,6 +113,13 @@ const View = (props) => {
143
113
 
144
114
  React.useEffect(() => {
145
115
  if (!mounted) return;
116
+
117
+ // set role="tablist" on RRT_tabs for proper aria role accessibility
118
+ const tabsWrapper = tabsContainer.current?.tabsWrapper.current;
119
+ if (tabsWrapper) {
120
+ tabsWrapper.querySelector('.RRT__tabs').setAttribute('role', 'tablist');
121
+ }
122
+
146
123
  const { blockWidth, tabsTotalWidth } = tabsContainer.current?.state || {};
147
124
  setInitialWidth(
148
125
  tabsTotalWidth < blockWidth ? tabsTotalWidth + 1 : blockWidth + 1,
@@ -170,7 +147,7 @@ const View = (props) => {
170
147
 
171
148
  return (
172
149
  <div
173
- tabIndex="0"
150
+ className={'tab-accordion-container'}
174
151
  onKeyDown={(e) => {
175
152
  if (e.key === 'Enter') {
176
153
  e.preventDefault();
@@ -178,7 +155,8 @@ const View = (props) => {
178
155
  if (focusedElement) focusedElement.click();
179
156
  }
180
157
  }}
181
- role="tab"
158
+ role={'presentation'}
159
+ tabIndex={-1}
182
160
  >
183
161
  <Tabs
184
162
  ref={tabsContainer}
@@ -209,13 +187,13 @@ const View = (props) => {
209
187
  : 'ui menu tabs-accessibility tabs-secondary-variant',
210
188
  data?.theme ? `${data?.theme}` : '',
211
189
  {
212
- inverted: getDataValue('menuInverted'),
190
+ inverted: data.menuInverted,
213
191
  },
214
192
  {
215
- pointing: getDataValue('menuPointing'),
193
+ pointing: data.menuPointing,
216
194
  },
217
195
  {
218
- secondary: getDataValue('menuSecondary'),
196
+ secondary: data.menuSecondary,
219
197
  },
220
198
  )}
221
199
  showMore={false}
@@ -1,5 +1,4 @@
1
1
  import AccordionEdit from './Edit';
2
2
  import AccordionView from './View';
3
- import accordionSchema from './schema';
4
3
 
5
- export { AccordionEdit, AccordionView, accordionSchema };
4
+ export { AccordionEdit, AccordionView };
@@ -1,4 +1,5 @@
1
1
  import { defineMessages } from 'react-intl';
2
+ import config from '@plone/volto/registry';
2
3
 
3
4
  const messages = defineMessages({
4
5
  AccordionTabsBlock: {
@@ -51,58 +52,50 @@ const messages = defineMessages({
51
52
  },
52
53
  });
53
54
 
54
- export default (config, props) => ({
55
- title: props.intl.formatMessage(messages.AccordionTabsBlock),
56
- fieldsets: [
57
- {
58
- id: 'default',
59
- title: props.intl.formatMessage(messages.Default),
60
- fields: ['description'],
61
- },
62
- {
63
- id: 'menu',
64
- title: props.intl.formatMessage(messages.Menu),
65
- fields: [
66
- 'menuInverted',
67
- 'menuSecondary',
68
- 'menuPointing',
69
- 'accordionIconRight',
70
- ],
71
- },
72
- {
73
- id: 'style',
74
- title: props.intl.formatMessage(messages.Style),
75
- fields: ['theme'],
76
- },
77
- ],
78
- properties: {
79
- description: {
80
- title: props.intl.formatMessage(messages.Description),
81
- },
55
+ export const accordionSchemaEnhancer = ({ schema, intl }) => {
56
+ schema.fieldsets.splice(1, 0, {
57
+ id: 'menu',
58
+ title: intl.formatMessage(messages.Menu),
59
+ fields: [
60
+ 'menuInverted',
61
+ 'menuSecondary',
62
+ 'menuPointing',
63
+ 'accordionIconRight',
64
+ ],
65
+ });
66
+
67
+ schema.fieldsets.splice(2, 0, {
68
+ id: 'style',
69
+ title: intl.formatMessage(messages.Style),
70
+ fields: ['theme'],
71
+ });
72
+
73
+ schema.properties = {
74
+ ...schema.properties,
82
75
  accordionIconRight: {
83
- title: props.intl.formatMessage(messages.IconPositionOnTheRight),
84
- description: props.intl.formatMessage(
76
+ title: intl.formatMessage(messages.IconPositionOnTheRight),
77
+ description: intl.formatMessage(
85
78
  messages.PositionLeftRightIconAccordionTab,
86
79
  ),
87
80
  type: 'boolean',
88
81
  },
89
82
  menuInverted: {
90
- title: props.intl.formatMessage(messages.Inverted),
83
+ title: intl.formatMessage(messages.Inverted),
91
84
  type: 'boolean',
92
85
  },
93
86
  menuPointing: {
94
- title: props.intl.formatMessage(messages.MenuPointing),
87
+ title: intl.formatMessage(messages.MenuPointing),
95
88
  type: 'boolean',
89
+ default: true,
96
90
  },
97
91
  menuSecondary: {
98
- title: props.intl.formatMessage(messages.MenuSecondary),
92
+ title: intl.formatMessage(messages.MenuSecondary),
99
93
  type: 'boolean',
94
+ default: true,
100
95
  },
101
96
  theme: {
102
- title: props.intl.formatMessage(messages.Theme),
103
- description: props.intl.formatMessage(
104
- messages.SetThemeAccordionTabsBlock,
105
- ),
97
+ title: intl.formatMessage(messages.Theme),
98
+ description: intl.formatMessage(messages.SetThemeAccordionTabsBlock),
106
99
  widget: 'theme_picker',
107
100
  colors: [
108
101
  ...(config.settings && config.settings.themeColors
@@ -113,6 +106,6 @@ export default (config, props) => ({
113
106
  : []),
114
107
  ],
115
108
  },
116
- },
117
- required: [],
118
- });
109
+ };
110
+ return schema;
111
+ };
@@ -6,6 +6,7 @@ import { Icon, RenderBlocks } from '@plone/volto/components';
6
6
 
7
7
  import rightArrowSVG from '@eeacms/volto-tabs-block/icons/right-key.svg';
8
8
  import leftArrowSVG from '@eeacms/volto-tabs-block/icons/left-key.svg';
9
+ import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/carousel/schema';
9
10
 
10
11
  import 'slick-carousel/slick/slick.css';
11
12
  import 'slick-carousel/slick/slick-theme.css';
@@ -189,4 +190,6 @@ const View = (props) => {
189
190
  );
190
191
  };
191
192
 
193
+ View.schemaEnhancer = carouselSchemaEnhancer;
194
+
192
195
  export default withRouter(View);
@@ -6,6 +6,7 @@ import { RenderBlocks } from '@plone/volto/components';
6
6
  import 'slick-carousel/slick/slick.css';
7
7
  import 'slick-carousel/slick/slick-theme.css';
8
8
  import '@eeacms/volto-tabs-block/less/carousel.less';
9
+ import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/carousel/schema';
9
10
 
10
11
  const Slider = loadable(() => import('react-slick'));
11
12
 
@@ -50,4 +51,6 @@ const View = (props) => {
50
51
  );
51
52
  };
52
53
 
54
+ View.schemaEnhancer = carouselSchemaEnhancer;
55
+
53
56
  export default withRouter(View);
@@ -1,5 +1,4 @@
1
1
  import HorizontalCarouselView from './HorizontalView';
2
2
  import VerticalCarouselView from './VerticalView';
3
- import carouselSchema from './schema';
4
3
 
5
- export { HorizontalCarouselView, VerticalCarouselView, carouselSchema };
4
+ export { HorizontalCarouselView, VerticalCarouselView };