@eeacms/volto-tabs-block 3.0.1 → 4.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.
- package/CHANGELOG.md +11 -13
- package/package.json +2 -2
- package/src/components/View.jsx +1 -0
- package/src/components/templates/accordion/View.jsx +42 -7
- package/src/components/templates/accordion/schema.js +25 -19
- package/src/components/templates/carousel/HorizontalView.jsx +37 -2
- package/src/components/templates/default/Edit.jsx +4 -1
- package/src/components/templates/default/View.jsx +24 -4
- package/src/components/templates/horizontal-responsive/View.jsx +53 -6
- package/src/less/menu.less +170 -6
- package/src/less/menu.variables +5 -0
- package/src/less/tabs.less +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ 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
|
+
### [4.0.0](https://github.com/eea/volto-tabs-block/compare/3.0.1...4.0.0) - 10 March 2023
|
|
8
|
+
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- chore(accordion): Cleanup menuColor [Alin Voinea - [`de63905`](https://github.com/eea/volto-tabs-block/commit/de639056210d426d64e2e4762aeec2e215563854)]
|
|
12
|
+
- chore(typo): Fix typo accesibilty [Alin Voinea - [`cc7754e`](https://github.com/eea/volto-tabs-block/commit/cc7754eeb2e224966f942b9053638c3db94d834c)]
|
|
13
|
+
|
|
14
|
+
#### :hammer_and_wrench: Others
|
|
15
|
+
|
|
16
|
+
- Release 4.0.0 [Alin Voinea - [`8fc4cc9`](https://github.com/eea/volto-tabs-block/commit/8fc4cc9d8dc71e623e6586b95871cb3b98dc385f)]
|
|
17
|
+
- test(Jenkins): Run tests and cypress with latest canary @plone/volto [Alin Voinea - [`3348950`](https://github.com/eea/volto-tabs-block/commit/334895036f8e367281abb35a20879c32dfbfc292)]
|
|
7
18
|
### [3.0.1](https://github.com/eea/volto-tabs-block/compare/3.0.0...3.0.1) - 16 November 2022
|
|
8
19
|
|
|
9
20
|
#### :hammer_and_wrench: Others
|
|
@@ -27,9 +38,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
27
38
|
|
|
28
39
|
#### :hammer_and_wrench: Others
|
|
29
40
|
|
|
30
|
-
- Add Sonarqube tag using marine-frontend addons list [EEA Jenkins - [`a00e419`](https://github.com/eea/volto-tabs-block/commit/a00e419aef4c82a25f277f5e25e3d512c7838264)]
|
|
31
41
|
- lint fix [David Ichim - [`c0a898c`](https://github.com/eea/volto-tabs-block/commit/c0a898c54461478baed2ac2f149ae580d4c89aeb)]
|
|
32
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`3b284e6`](https://github.com/eea/volto-tabs-block/commit/3b284e65e0eafa9b5ad8c92b4cb77628ffcc8103)]
|
|
33
42
|
### [2.2.0](https://github.com/eea/volto-tabs-block/compare/2.1.0...2.2.0) - 25 August 2022
|
|
34
43
|
|
|
35
44
|
#### :hammer_and_wrench: Others
|
|
@@ -45,7 +54,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
45
54
|
|
|
46
55
|
- Release 2.1.0 [Alin Voinea - [`3cdfa30`](https://github.com/eea/volto-tabs-block/commit/3cdfa30d4d03d864be8ad63f0648b4717298734a)]
|
|
47
56
|
- Squashed commit of the following: [Alin Voinea - [`ca241f5`](https://github.com/eea/volto-tabs-block/commit/ca241f56a96817679a1948154e2a8cc0e17b96fe)]
|
|
48
|
-
- Add Sonarqube tag using circularity-frontend addons list [EEA Jenkins - [`68ea5a6`](https://github.com/eea/volto-tabs-block/commit/68ea5a6b971fc36840cf5716a04f68316b229b2b)]
|
|
49
57
|
### [2.0.2](https://github.com/eea/volto-tabs-block/compare/2.0.1...2.0.2) - 16 June 2022
|
|
50
58
|
|
|
51
59
|
### [2.0.1](https://github.com/eea/volto-tabs-block/compare/2.0.0...2.0.1) - 10 June 2022
|
|
@@ -89,8 +97,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
89
97
|
- Let theme addon to set default values for default template schema [Miu Razvan - [`55f148d`](https://github.com/eea/volto-tabs-block/commit/55f148d1a95417f8a0b55681ce250acde8463c1c)]
|
|
90
98
|
- Render pane as container if tabs-block has full-width class [Miu Razvan - [`bbffb96`](https://github.com/eea/volto-tabs-block/commit/bbffb96b908476ddee447af3ce79bafb1a12f9a8)]
|
|
91
99
|
- Refactor default template [Miu Razvan - [`58eff52`](https://github.com/eea/volto-tabs-block/commit/58eff5281adb08a5f8fe6d21fd43330252012277)]
|
|
92
|
-
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`72a6735`](https://github.com/eea/volto-tabs-block/commit/72a6735cbbc0e7d57b4bb7ea83fea9becc317018)]
|
|
93
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`e928da1`](https://github.com/eea/volto-tabs-block/commit/e928da1df7e4680bd4be9b5d46406800d721b8c5)]
|
|
94
100
|
### [1.2.12](https://github.com/eea/volto-tabs-block/compare/1.2.11...1.2.12) - 21 January 2022
|
|
95
101
|
|
|
96
102
|
### [1.2.11](https://github.com/eea/volto-tabs-block/compare/1.2.10...1.2.11) - 4 January 2022
|
|
@@ -105,17 +111,11 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
105
111
|
|
|
106
112
|
#### :hammer_and_wrench: Others
|
|
107
113
|
|
|
108
|
-
- Add Sonarqube tag using freshwater-frontend addons list [EEA Jenkins - [`cd2e2ac`](https://github.com/eea/volto-tabs-block/commit/cd2e2ac1d127bfc688ecf16e17734603ab727a34)]
|
|
109
114
|
### [1.2.8](https://github.com/eea/volto-tabs-block/compare/1.2.7...1.2.8) - 10 December 2021
|
|
110
115
|
|
|
111
116
|
#### :hammer_and_wrench: Others
|
|
112
117
|
|
|
113
118
|
- Refs #142010 - Optimize Volto-addons gitflow pipelines [valentinab25 - [`d10c0b3`](https://github.com/eea/volto-tabs-block/commit/d10c0b3d35d25c530d19eebde38dfe5da8fda01b)]
|
|
114
|
-
- Add Sonarqube tag using industry-frontend addons list [EEA Jenkins - [`1a7187f`](https://github.com/eea/volto-tabs-block/commit/1a7187f10b2bd9e1307dabf51823f63ccd766864)]
|
|
115
|
-
- Add Sonarqube tag using clms-frontend addons list [EEA Jenkins - [`72a7550`](https://github.com/eea/volto-tabs-block/commit/72a755025b38e1d8dd7fe206273a70585e4b9ac8)]
|
|
116
|
-
- Add Sonarqube tag using forests-frontend addons list [EEA Jenkins - [`022b277`](https://github.com/eea/volto-tabs-block/commit/022b2779a5d7fd7217c2d8a559eafab0bd86ce23)]
|
|
117
|
-
- Add Sonarqube tag using sustainability-frontend addons list [EEA Jenkins - [`84c9bea`](https://github.com/eea/volto-tabs-block/commit/84c9bea7a0aba2fe9ef9713e7131de6da6e0bcce)]
|
|
118
|
-
- Add Sonarqube tag using ims-frontend addons list [EEA Jenkins - [`020aa97`](https://github.com/eea/volto-tabs-block/commit/020aa97bc70a643ea3857566c5a1dc3a5200c2be)]
|
|
119
119
|
### [1.2.7](https://github.com/eea/volto-tabs-block/compare/1.2.6...1.2.7) - 27 August 2021
|
|
120
120
|
|
|
121
121
|
#### :hammer_and_wrench: Others
|
|
@@ -132,8 +132,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
132
132
|
|
|
133
133
|
- Move less import in View instead of Edit [Tiberiu Ichim - [`84aeff0`](https://github.com/eea/volto-tabs-block/commit/84aeff04a980076f54687c546691d37b6e790478)]
|
|
134
134
|
- gitignore tweaks [Tiberiu Ichim - [`f4c993d`](https://github.com/eea/volto-tabs-block/commit/f4c993d004b126f08f16651ab9460546fa9e9cad)]
|
|
135
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`865906a`](https://github.com/eea/volto-tabs-block/commit/865906a0deb261d44cc23e26bfd2d1dd0e319640)]
|
|
136
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`5383861`](https://github.com/eea/volto-tabs-block/commit/538386100adbc868e693c1c2a5ba13461307ffee)]
|
|
137
135
|
- Style update [razvanMiu - [`323aaaf`](https://github.com/eea/volto-tabs-block/commit/323aaafcad01d8fdf0e713a1fc254ae9fe319f43)]
|
|
138
136
|
- Fix 'scroll to' feature on carousel [razvanMiu - [`16c6a08`](https://github.com/eea/volto-tabs-block/commit/16c6a08f6db687542ea38e07a92b265e592f6173)]
|
|
139
137
|
- Better accesibility [razvanMiu - [`3511611`](https://github.com/eea/volto-tabs-block/commit/351161197270a4807f01d85a7055cbaadae72f8e)]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-tabs-block",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.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",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"slick-carousel": "^1.8.1"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@plone/scripts": "*",
|
|
30
29
|
"@cypress/code-coverage": "^3.10.0",
|
|
30
|
+
"@plone/scripts": "*",
|
|
31
31
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
32
32
|
"md5": "^2.3.0"
|
|
33
33
|
},
|
package/src/components/View.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useLayoutEffect } from 'react';
|
|
2
2
|
import cx from 'classnames';
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import { withRouter } from 'react-router';
|
|
@@ -31,7 +31,12 @@ class Tab extends React.Component {
|
|
|
31
31
|
|
|
32
32
|
render() {
|
|
33
33
|
return (
|
|
34
|
-
<AnimateHeight
|
|
34
|
+
<AnimateHeight
|
|
35
|
+
animateOpacity
|
|
36
|
+
duration={500}
|
|
37
|
+
height={this.state.height}
|
|
38
|
+
aria-hidden={false}
|
|
39
|
+
>
|
|
35
40
|
<RenderBlocks {...this.props} />
|
|
36
41
|
</AnimateHeight>
|
|
37
42
|
);
|
|
@@ -45,7 +50,9 @@ const View = (props) => {
|
|
|
45
50
|
tabs = {},
|
|
46
51
|
activeTabIndex = 0,
|
|
47
52
|
setActiveTab = () => {},
|
|
53
|
+
id,
|
|
48
54
|
} = props;
|
|
55
|
+
|
|
49
56
|
const accordionConfig =
|
|
50
57
|
config.blocks.blocksConfig[TABS_BLOCK].templates?.['accordion'] || {};
|
|
51
58
|
const { icons, semanticIcon, transformWidth = 800 } = accordionConfig;
|
|
@@ -94,7 +101,9 @@ const View = (props) => {
|
|
|
94
101
|
{title || defaultTitle}{' '}
|
|
95
102
|
</>
|
|
96
103
|
),
|
|
97
|
-
getContent: () =>
|
|
104
|
+
getContent: () => (
|
|
105
|
+
<Tab {...props} tab={tab} content={tabs[tab]} aria-hidden={false} />
|
|
106
|
+
),
|
|
98
107
|
key: tab,
|
|
99
108
|
tabClassName: cx('ui button item title', { active }),
|
|
100
109
|
panelClassName: cx('ui bottom attached segment tab', {
|
|
@@ -115,12 +124,36 @@ const View = (props) => {
|
|
|
115
124
|
);
|
|
116
125
|
}, [mounted]);
|
|
117
126
|
|
|
127
|
+
useLayoutEffect(() => {
|
|
128
|
+
if (document.activeElement.role !== 'tab') return;
|
|
129
|
+
if (
|
|
130
|
+
document.getElementById(id)?.getElementsByClassName('tab active').length >
|
|
131
|
+
0
|
|
132
|
+
) {
|
|
133
|
+
let activeTabDiv = document
|
|
134
|
+
.getElementById(id)
|
|
135
|
+
.getElementsByClassName('tab active')[0];
|
|
136
|
+
activeTabDiv.setAttribute('tabindex', '0');
|
|
137
|
+
activeTabDiv.setAttribute('className', 'accessibility-accordion-tab');
|
|
138
|
+
activeTabDiv.focus();
|
|
139
|
+
}
|
|
140
|
+
}, [activeTabIndex, id]);
|
|
141
|
+
|
|
118
142
|
return (
|
|
119
|
-
|
|
143
|
+
<div
|
|
144
|
+
tabIndex="0"
|
|
145
|
+
onKeyDown={(e) => {
|
|
146
|
+
if (e.key === 'Enter') {
|
|
147
|
+
e.preventDefault();
|
|
148
|
+
const focusedElement = document.activeElement;
|
|
149
|
+
if (focusedElement) focusedElement.click();
|
|
150
|
+
}
|
|
151
|
+
}}
|
|
152
|
+
role="tab"
|
|
153
|
+
>
|
|
120
154
|
<Tabs
|
|
121
155
|
ref={tabsContainer}
|
|
122
156
|
transformWidth={initialWidth}
|
|
123
|
-
className="tabs aa"
|
|
124
157
|
selectedTabKey={tabsList[activeTabIndex]}
|
|
125
158
|
items={items}
|
|
126
159
|
onChange={(tab) => {
|
|
@@ -131,15 +164,17 @@ const View = (props) => {
|
|
|
131
164
|
}
|
|
132
165
|
}}
|
|
133
166
|
tabsWrapperClass={cx(
|
|
167
|
+
props?.data?.accordionIconRight ? 'tabs-accordion-icon-right' : '',
|
|
134
168
|
'ui pointing secondary menu',
|
|
135
|
-
|
|
169
|
+
'tabs-accessibility',
|
|
170
|
+
data?.theme ? `theme-${data?.theme}` : '',
|
|
136
171
|
{
|
|
137
172
|
inverted: getDataValue('menuInverted'),
|
|
138
173
|
},
|
|
139
174
|
)}
|
|
140
175
|
showMore={false}
|
|
141
176
|
/>
|
|
142
|
-
|
|
177
|
+
</div>
|
|
143
178
|
);
|
|
144
179
|
};
|
|
145
180
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import config from '@plone/volto/registry';
|
|
2
|
+
|
|
1
3
|
export default () => ({
|
|
2
4
|
title: 'Accordion tabs block',
|
|
3
5
|
fieldsets: [
|
|
@@ -9,36 +11,40 @@ export default () => ({
|
|
|
9
11
|
{
|
|
10
12
|
id: 'menu',
|
|
11
13
|
title: 'Menu',
|
|
12
|
-
fields: ['
|
|
14
|
+
fields: ['menuInverted', 'accordionIconRight'],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: 'style',
|
|
18
|
+
title: 'Style',
|
|
19
|
+
fields: ['theme'],
|
|
13
20
|
},
|
|
14
21
|
],
|
|
15
22
|
properties: {
|
|
16
23
|
description: {
|
|
17
24
|
title: 'Description',
|
|
18
25
|
},
|
|
19
|
-
|
|
20
|
-
title: '
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
],
|
|
26
|
+
accordionIconRight: {
|
|
27
|
+
title: 'Icon position on the right',
|
|
28
|
+
description: 'Position left/right of the icon in the accordion tab',
|
|
29
|
+
type: 'boolean',
|
|
37
30
|
},
|
|
38
31
|
menuInverted: {
|
|
39
32
|
title: 'Inverted',
|
|
40
33
|
type: 'boolean',
|
|
41
34
|
},
|
|
35
|
+
theme: {
|
|
36
|
+
title: 'Theme',
|
|
37
|
+
description: 'Set the theme for the accordion tabs block',
|
|
38
|
+
widget: 'theme_picker',
|
|
39
|
+
colors: [
|
|
40
|
+
...(config.settings && config.settings.themeColors
|
|
41
|
+
? config.settings.themeColors.map(({ value, title }) => ({
|
|
42
|
+
name: value,
|
|
43
|
+
label: title,
|
|
44
|
+
}))
|
|
45
|
+
: []),
|
|
46
|
+
],
|
|
47
|
+
},
|
|
42
48
|
},
|
|
43
49
|
required: [],
|
|
44
50
|
});
|
|
@@ -29,6 +29,7 @@ const Dots = (props) => {
|
|
|
29
29
|
>
|
|
30
30
|
<button
|
|
31
31
|
aria-label={`Select slide ${index + 1}`}
|
|
32
|
+
tabIndex={0}
|
|
32
33
|
onClick={() => {
|
|
33
34
|
if (slider.current) {
|
|
34
35
|
slider.current.slickGoTo(index);
|
|
@@ -65,6 +66,7 @@ const ArrowsGroup = (props) => {
|
|
|
65
66
|
slider.current.slickPrev();
|
|
66
67
|
}
|
|
67
68
|
}}
|
|
69
|
+
tabIndex={0}
|
|
68
70
|
>
|
|
69
71
|
<Icon name={leftArrowSVG} size="50px" />
|
|
70
72
|
</button>
|
|
@@ -80,6 +82,7 @@ const ArrowsGroup = (props) => {
|
|
|
80
82
|
slider.current.slickNext();
|
|
81
83
|
}
|
|
82
84
|
}}
|
|
85
|
+
tabIndex={0}
|
|
83
86
|
>
|
|
84
87
|
<Icon name={rightArrowSVG} size="50px" />
|
|
85
88
|
</button>
|
|
@@ -93,6 +96,7 @@ const ArrowsGroup = (props) => {
|
|
|
93
96
|
const View = (props) => {
|
|
94
97
|
const slider = React.useRef(null);
|
|
95
98
|
const [hashlinkOnMount, setHashlinkOnMount] = React.useState(false);
|
|
99
|
+
const blockId = props.id;
|
|
96
100
|
const {
|
|
97
101
|
activeTab = null,
|
|
98
102
|
data = {},
|
|
@@ -128,10 +132,24 @@ const View = (props) => {
|
|
|
128
132
|
for (let element of slider.current.innerSlider.list.querySelectorAll(
|
|
129
133
|
".slick-slide[aria-hidden='true'] a",
|
|
130
134
|
)) {
|
|
131
|
-
element.setAttribute('aria-
|
|
135
|
+
element.setAttribute('aria-hidden', 'false');
|
|
132
136
|
}
|
|
133
137
|
});
|
|
134
138
|
}, [activeTab]);
|
|
139
|
+
React.useEffect(() => {
|
|
140
|
+
if (!slider.current?.innerSlider?.list) return;
|
|
141
|
+
let unaccesibileElements = slider.current.innerSlider.list.querySelectorAll(
|
|
142
|
+
'.slick-slide',
|
|
143
|
+
);
|
|
144
|
+
for (let element of unaccesibileElements) {
|
|
145
|
+
element.setAttribute('tabindex', '0');
|
|
146
|
+
element.setAttribute('aria-hidden', 'false');
|
|
147
|
+
element.style.removeProperty('outline');
|
|
148
|
+
}
|
|
149
|
+
if (document.getElementsByClassName('slick-slider')?.length > 0)
|
|
150
|
+
for (let carouselDiv of document.getElementsByClassName('slick-slider'))
|
|
151
|
+
carouselDiv.setAttribute('tabindex', '0');
|
|
152
|
+
}, []);
|
|
135
153
|
|
|
136
154
|
React.useEffect(() => {
|
|
137
155
|
const urlHash = props.location.hash.substring(1) || '';
|
|
@@ -183,7 +201,24 @@ const View = (props) => {
|
|
|
183
201
|
|
|
184
202
|
return (
|
|
185
203
|
<>
|
|
186
|
-
<Slider
|
|
204
|
+
<Slider
|
|
205
|
+
{...settings}
|
|
206
|
+
ref={slider}
|
|
207
|
+
className={cx(uiContainer, 'tabs-accessibility')}
|
|
208
|
+
accessibility={true}
|
|
209
|
+
afterChange={() => {
|
|
210
|
+
if (
|
|
211
|
+
document
|
|
212
|
+
.getElementById(blockId)
|
|
213
|
+
?.getElementsByClassName('slick-slider')?.length > 0
|
|
214
|
+
) {
|
|
215
|
+
document
|
|
216
|
+
.getElementById(blockId)
|
|
217
|
+
.getElementsByClassName('slick-current')[0]
|
|
218
|
+
.focus();
|
|
219
|
+
}
|
|
220
|
+
}}
|
|
221
|
+
>
|
|
187
222
|
{panes.length ? panes.map((pane) => pane.renderItem) : ''}
|
|
188
223
|
</Slider>
|
|
189
224
|
<ArrowsGroup activeTab={activeTab} tabsList={tabsList} slider={slider} />
|
|
@@ -274,7 +274,10 @@ const Edit = (props) => {
|
|
|
274
274
|
menu={{
|
|
275
275
|
attached: menuPosition.attached,
|
|
276
276
|
borderless: getDataValue('menuBorderless'),
|
|
277
|
-
color:
|
|
277
|
+
color:
|
|
278
|
+
props?.template === 'accordion' && props?.data?.theme
|
|
279
|
+
? `theme-${props?.data?.theme}`
|
|
280
|
+
: getDataValue('menuColor'),
|
|
278
281
|
compact: getDataValue('menuCompact'),
|
|
279
282
|
fluid: getDataValue('menuFluid'),
|
|
280
283
|
inverted: getDataValue('menuInverted'),
|
|
@@ -22,11 +22,12 @@ const MenuItem = (props) => {
|
|
|
22
22
|
setActiveTab = () => {},
|
|
23
23
|
tabsTitle,
|
|
24
24
|
tabsDescription,
|
|
25
|
+
blockId,
|
|
25
26
|
} = props;
|
|
27
|
+
|
|
26
28
|
const { tab, index } = props;
|
|
27
29
|
const title = tabs[tab].title;
|
|
28
30
|
const tabIndex = index + 1;
|
|
29
|
-
|
|
30
31
|
const defaultTitle = `Tab ${tabIndex}`;
|
|
31
32
|
|
|
32
33
|
return (
|
|
@@ -40,11 +41,30 @@ const MenuItem = (props) => {
|
|
|
40
41
|
<Menu.Item
|
|
41
42
|
name={defaultTitle}
|
|
42
43
|
active={tab === activeTab}
|
|
44
|
+
tabIndex={0}
|
|
43
45
|
onClick={() => {
|
|
44
46
|
if (activeTab !== tab) {
|
|
45
47
|
setActiveTab(tab);
|
|
46
48
|
}
|
|
47
49
|
}}
|
|
50
|
+
onKeyDown={(e) => {
|
|
51
|
+
if (e.key === 'Enter') {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
if (
|
|
54
|
+
document
|
|
55
|
+
.getElementById(blockId)
|
|
56
|
+
?.getElementsByClassName('active tab').length > 0
|
|
57
|
+
) {
|
|
58
|
+
const tabDiv = document
|
|
59
|
+
.getElementById(blockId)
|
|
60
|
+
.getElementsByClassName('active tab')[0];
|
|
61
|
+
tabDiv.focus();
|
|
62
|
+
}
|
|
63
|
+
if (activeTab !== tab) {
|
|
64
|
+
setActiveTab(tab);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}}
|
|
48
68
|
>
|
|
49
69
|
<span className={'menu-item-count'}>{tabIndex}</span>
|
|
50
70
|
<p className={'menu-item-text'}>{title || defaultTitle}</p>
|
|
@@ -64,7 +84,6 @@ const View = (props) => {
|
|
|
64
84
|
hashlink = {},
|
|
65
85
|
setActiveTab = () => {},
|
|
66
86
|
} = props;
|
|
67
|
-
|
|
68
87
|
const [menuPosition, setMenuPosition] = React.useState({});
|
|
69
88
|
|
|
70
89
|
React.useEffect(() => {
|
|
@@ -134,11 +153,12 @@ const View = (props) => {
|
|
|
134
153
|
index={index}
|
|
135
154
|
tabsTitle={tabsTitle}
|
|
136
155
|
tabsDescription={tabsDescription}
|
|
156
|
+
blockId={props?.id || ''}
|
|
137
157
|
/>
|
|
138
158
|
),
|
|
139
159
|
render: () => {
|
|
140
160
|
return (
|
|
141
|
-
<Tab.Pane as={isContainer ? Container : undefined}>
|
|
161
|
+
<Tab.Pane as={isContainer ? Container : undefined} tabIndex={0}>
|
|
142
162
|
<RenderBlocks {...props} metadata={metadata} content={tabs[tab]} />
|
|
143
163
|
</Tab.Pane>
|
|
144
164
|
);
|
|
@@ -150,7 +170,7 @@ const View = (props) => {
|
|
|
150
170
|
<>
|
|
151
171
|
<Tab
|
|
152
172
|
activeIndex={activeTabIndex}
|
|
153
|
-
className="default tabs"
|
|
173
|
+
className="default tabs tabs-accessibility"
|
|
154
174
|
menu={{
|
|
155
175
|
attached: menuPosition.attached,
|
|
156
176
|
borderless: getDataValue('menuBorderless'),
|
|
@@ -18,30 +18,76 @@ import {
|
|
|
18
18
|
import '@eeacms/volto-tabs-block/less/menu.less';
|
|
19
19
|
|
|
20
20
|
const MenuItem = (props) => {
|
|
21
|
-
const {
|
|
21
|
+
const {
|
|
22
|
+
activeTab = null,
|
|
23
|
+
tabs = {},
|
|
24
|
+
setActiveTab = () => {},
|
|
25
|
+
blockId,
|
|
26
|
+
} = props;
|
|
22
27
|
const { tabsTitle, tabsDescription, tab, index } = props;
|
|
23
28
|
const title = tabs[tab].title;
|
|
24
29
|
const tabIndex = index + 1;
|
|
25
|
-
|
|
26
30
|
const defaultTitle = `Tab ${tabIndex}`;
|
|
27
31
|
|
|
28
32
|
return (
|
|
29
33
|
<React.Fragment>
|
|
30
34
|
{index === 0 && (tabsTitle || tabsDescription) && (
|
|
31
|
-
<Menu.Item
|
|
35
|
+
<Menu.Item
|
|
36
|
+
className="menu-title"
|
|
37
|
+
tabIndex={0}
|
|
38
|
+
onKeyDown={(e) => {
|
|
39
|
+
if (e.key === 'Enter') {
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
if (
|
|
42
|
+
document
|
|
43
|
+
.getElementById(blockId)
|
|
44
|
+
?.getElementsByClassName('active tab')?.length > 0
|
|
45
|
+
) {
|
|
46
|
+
const tabDiv = document
|
|
47
|
+
.getElementById(blockId)
|
|
48
|
+
.getElementsByClassName('active tab')[0];
|
|
49
|
+
tabDiv.focus();
|
|
50
|
+
}
|
|
51
|
+
if (activeTab !== tab) {
|
|
52
|
+
setActiveTab(tab);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
32
57
|
<SimpleMarkdown md={tabsTitle} defaultTag="##" className="title" />
|
|
33
58
|
<SimpleMarkdown md={tabsDescription} className="description" />
|
|
34
59
|
</Menu.Item>
|
|
35
60
|
)}
|
|
36
61
|
<Button
|
|
37
62
|
as="a"
|
|
38
|
-
|
|
63
|
+
tabIndex={0}
|
|
64
|
+
className={cx('item', 'accesibility-button', {
|
|
65
|
+
active: tab === activeTab,
|
|
66
|
+
})}
|
|
39
67
|
item-data={tab}
|
|
40
68
|
onClick={() => {
|
|
41
69
|
if (activeTab !== tab) {
|
|
42
70
|
setActiveTab(tab);
|
|
43
71
|
}
|
|
44
72
|
}}
|
|
73
|
+
onKeyDown={(e) => {
|
|
74
|
+
if (e.key === 'Enter') {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
if (
|
|
77
|
+
document
|
|
78
|
+
.getElementById(blockId)
|
|
79
|
+
?.getElementsByClassName('active tab').length > 0
|
|
80
|
+
) {
|
|
81
|
+
const tabDiv = document
|
|
82
|
+
.getElementById(blockId)
|
|
83
|
+
.getElementsByClassName('active tab')[0];
|
|
84
|
+
tabDiv.focus();
|
|
85
|
+
}
|
|
86
|
+
if (activeTab !== tab) {
|
|
87
|
+
setActiveTab(tab);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}}
|
|
45
91
|
>
|
|
46
92
|
<span className={'menu-item-count'}>{tabIndex}</span>
|
|
47
93
|
<p className={'menu-item-text'}>{title || defaultTitle}</p>
|
|
@@ -92,7 +138,7 @@ const MenuWrapper = (props) => {
|
|
|
92
138
|
|
|
93
139
|
return (
|
|
94
140
|
<React.Fragment>
|
|
95
|
-
<div className="menu-wrapper">
|
|
141
|
+
<div className="menu-wrapper tabs-accessibility">
|
|
96
142
|
{panes.map((pane, index) => (
|
|
97
143
|
<React.Fragment key={`menu-item-${index}-${pane.id}`}>
|
|
98
144
|
{pane.menuItem}
|
|
@@ -207,6 +253,7 @@ const View = (props) => {
|
|
|
207
253
|
key={tab}
|
|
208
254
|
tab={tab}
|
|
209
255
|
tabsList={tabsList}
|
|
256
|
+
blockId={props.id}
|
|
210
257
|
index={index}
|
|
211
258
|
lastIndex={tabsList.length - 1}
|
|
212
259
|
tabsTitle={tabsTitle}
|
|
@@ -216,7 +263,7 @@ const View = (props) => {
|
|
|
216
263
|
render: () => {
|
|
217
264
|
return (
|
|
218
265
|
<>
|
|
219
|
-
<Tab.Pane as={isContainer ? Container : undefined}>
|
|
266
|
+
<Tab.Pane as={isContainer ? Container : undefined} tabIndex={0}>
|
|
220
267
|
<RenderBlocks
|
|
221
268
|
{...props}
|
|
222
269
|
metadata={metadata}
|
package/src/less/menu.less
CHANGED
|
@@ -55,12 +55,10 @@
|
|
|
55
55
|
flex-direction: column;
|
|
56
56
|
align-items: flex-start;
|
|
57
57
|
justify-content: center;
|
|
58
|
-
background: @menuTitleBackgrounnd;
|
|
59
58
|
font-size: @menuTitleFontSize;
|
|
60
59
|
font-weight: @menuTitleFontWeight;
|
|
61
60
|
|
|
62
61
|
&:hover {
|
|
63
|
-
background: @menuTitleHoverBackground;
|
|
64
62
|
color: @menuTitleHoverColor;
|
|
65
63
|
}
|
|
66
64
|
|
|
@@ -143,6 +141,13 @@
|
|
|
143
141
|
}
|
|
144
142
|
}
|
|
145
143
|
|
|
144
|
+
.ui.menu.RRT__accordion.tabs-accordion-icon-right {
|
|
145
|
+
.ui.item {
|
|
146
|
+
flex-direction: row-reverse;
|
|
147
|
+
justify-content: space-between;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
146
151
|
.ui.menu.RRT__accordion {
|
|
147
152
|
&::before {
|
|
148
153
|
display: none;
|
|
@@ -153,11 +158,9 @@
|
|
|
153
158
|
.ui.item {
|
|
154
159
|
display: flex;
|
|
155
160
|
width: 100%;
|
|
156
|
-
padding: 0
|
|
157
|
-
border-
|
|
158
|
-
border-bottom: none !important;
|
|
161
|
+
padding: 0 1rem !important;
|
|
162
|
+
border-bottom: 0.0625rem solid #e6e7e8;
|
|
159
163
|
margin: 0 !important;
|
|
160
|
-
background-color: @accordionMenuItemBackground;
|
|
161
164
|
|
|
162
165
|
.icon {
|
|
163
166
|
margin: 0 !important;
|
|
@@ -174,7 +177,58 @@
|
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
179
|
|
|
180
|
+
.RRT__tab:not(.active) .icon {
|
|
181
|
+
color: #808285;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
&.theme-primary {
|
|
185
|
+
.ui.item:not(.active):hover {
|
|
186
|
+
color: @primaryColor !important;
|
|
187
|
+
|
|
188
|
+
.icon {
|
|
189
|
+
color: @primaryColor !important;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.ui.item.active {
|
|
194
|
+
background-color: @primaryColor !important;
|
|
195
|
+
color: #fff !important;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&.theme-secondary {
|
|
200
|
+
.ui.item:not(.active):hover {
|
|
201
|
+
color: @secondaryColor !important;
|
|
202
|
+
|
|
203
|
+
.icon {
|
|
204
|
+
color: @secondaryColor !important;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.ui.item.active {
|
|
209
|
+
background-color: @secondaryColor !important;
|
|
210
|
+
color: #fff !important;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
&.theme-tertiary {
|
|
215
|
+
.ui.item:not(.active):hover {
|
|
216
|
+
color: @tertiaryColor !important;
|
|
217
|
+
|
|
218
|
+
.icon {
|
|
219
|
+
color: @tertiaryColor !important;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.ui.item.active {
|
|
224
|
+
background-color: @tertiaryColor !important;
|
|
225
|
+
color: #fff !important;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
177
229
|
&.red {
|
|
230
|
+
color: @red !important;
|
|
231
|
+
|
|
178
232
|
.ui.item.active {
|
|
179
233
|
background-color: @red !important;
|
|
180
234
|
color: #fff !important;
|
|
@@ -182,6 +236,10 @@
|
|
|
182
236
|
}
|
|
183
237
|
|
|
184
238
|
&.orange {
|
|
239
|
+
.ui.item:hover {
|
|
240
|
+
color: @orange !important;
|
|
241
|
+
}
|
|
242
|
+
|
|
185
243
|
.ui.item.active {
|
|
186
244
|
background-color: @orange !important;
|
|
187
245
|
color: #fff !important;
|
|
@@ -189,6 +247,10 @@
|
|
|
189
247
|
}
|
|
190
248
|
|
|
191
249
|
&.yellow {
|
|
250
|
+
.ui.item:hover {
|
|
251
|
+
color: @yellow !important;
|
|
252
|
+
}
|
|
253
|
+
|
|
192
254
|
.ui.item.active {
|
|
193
255
|
background-color: @yellow !important;
|
|
194
256
|
color: #fff !important;
|
|
@@ -196,6 +258,10 @@
|
|
|
196
258
|
}
|
|
197
259
|
|
|
198
260
|
&.olive {
|
|
261
|
+
.ui.item:hover {
|
|
262
|
+
color: @olive !important;
|
|
263
|
+
}
|
|
264
|
+
|
|
199
265
|
.ui.item.active {
|
|
200
266
|
background-color: @olive !important;
|
|
201
267
|
color: #fff !important;
|
|
@@ -203,6 +269,10 @@
|
|
|
203
269
|
}
|
|
204
270
|
|
|
205
271
|
&.green {
|
|
272
|
+
.ui.item:hover {
|
|
273
|
+
color: @green !important;
|
|
274
|
+
}
|
|
275
|
+
|
|
206
276
|
.ui.item.active {
|
|
207
277
|
background-color: @green !important;
|
|
208
278
|
color: #fff !important;
|
|
@@ -210,6 +280,10 @@
|
|
|
210
280
|
}
|
|
211
281
|
|
|
212
282
|
&.teal {
|
|
283
|
+
.ui.item:hover {
|
|
284
|
+
color: @teal !important;
|
|
285
|
+
}
|
|
286
|
+
|
|
213
287
|
.ui.item.active {
|
|
214
288
|
background-color: @teal !important;
|
|
215
289
|
color: #fff !important;
|
|
@@ -217,6 +291,10 @@
|
|
|
217
291
|
}
|
|
218
292
|
|
|
219
293
|
&.blue {
|
|
294
|
+
.ui.item:hover {
|
|
295
|
+
color: @blue !important;
|
|
296
|
+
}
|
|
297
|
+
|
|
220
298
|
.ui.item.active {
|
|
221
299
|
background-color: @blue !important;
|
|
222
300
|
color: #fff !important;
|
|
@@ -224,6 +302,10 @@
|
|
|
224
302
|
}
|
|
225
303
|
|
|
226
304
|
&.violet {
|
|
305
|
+
.ui.item:hover {
|
|
306
|
+
color: @violet !important;
|
|
307
|
+
}
|
|
308
|
+
|
|
227
309
|
.ui.item.active {
|
|
228
310
|
background-color: @violet !important;
|
|
229
311
|
color: #fff !important;
|
|
@@ -231,6 +313,10 @@
|
|
|
231
313
|
}
|
|
232
314
|
|
|
233
315
|
&.purple {
|
|
316
|
+
.ui.item:hover {
|
|
317
|
+
color: @purple !important;
|
|
318
|
+
}
|
|
319
|
+
|
|
234
320
|
.ui.item.active {
|
|
235
321
|
background-color: @purple !important;
|
|
236
322
|
color: #fff !important;
|
|
@@ -238,6 +324,10 @@
|
|
|
238
324
|
}
|
|
239
325
|
|
|
240
326
|
&.brown {
|
|
327
|
+
.ui.item:hover {
|
|
328
|
+
color: @brown !important;
|
|
329
|
+
}
|
|
330
|
+
|
|
241
331
|
.ui.item.active {
|
|
242
332
|
background-color: @brown !important;
|
|
243
333
|
color: #fff !important;
|
|
@@ -245,6 +335,10 @@
|
|
|
245
335
|
}
|
|
246
336
|
|
|
247
337
|
&.grey {
|
|
338
|
+
.ui.item:hover {
|
|
339
|
+
color: @grey !important;
|
|
340
|
+
}
|
|
341
|
+
|
|
248
342
|
.ui.item.active {
|
|
249
343
|
background-color: @grey !important;
|
|
250
344
|
color: #fff !important;
|
|
@@ -252,6 +346,10 @@
|
|
|
252
346
|
}
|
|
253
347
|
|
|
254
348
|
&.black {
|
|
349
|
+
.ui.item:hover {
|
|
350
|
+
color: @black !important;
|
|
351
|
+
}
|
|
352
|
+
|
|
255
353
|
.ui.item.active {
|
|
256
354
|
background-color: @black !important;
|
|
257
355
|
color: #fff !important;
|
|
@@ -266,4 +364,70 @@
|
|
|
266
364
|
}
|
|
267
365
|
}
|
|
268
366
|
|
|
367
|
+
.ui.menu.RRT__tabs {
|
|
368
|
+
.item.ui {
|
|
369
|
+
color: #323232;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
&.theme-primary {
|
|
373
|
+
.item.ui:hover {
|
|
374
|
+
color: @primaryColor !important;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
.item.ui.active {
|
|
378
|
+
border-bottom: 0.1875rem solid @primaryColor !important;
|
|
379
|
+
color: @primaryColor !important;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
&.theme-secondary {
|
|
384
|
+
.item.ui:hover {
|
|
385
|
+
color: @secondaryColor !important;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.item.ui.active {
|
|
389
|
+
border-bottom: 0.1875rem solid @secondaryColor !important;
|
|
390
|
+
color: @secondaryColor !important;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
&.theme-tertiary {
|
|
395
|
+
.item.ui:hover {
|
|
396
|
+
color: @tertiaryColor !important;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.ui.item.active {
|
|
400
|
+
border-bottom: 0.1875rem solid @tertiaryColor !important;
|
|
401
|
+
color: @tertiaryColor !important;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.tabs-block {
|
|
407
|
+
.theme-primary {
|
|
408
|
+
.active.item {
|
|
409
|
+
border-bottom: 0.1875rem solid @primaryColor !important;
|
|
410
|
+
color: @primaryColor !important;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.theme-secondary {
|
|
415
|
+
.active.item {
|
|
416
|
+
border-bottom: 0.1875rem solid @secondaryColor !important;
|
|
417
|
+
color: @secondaryColor !important;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.theme-tertiary {
|
|
422
|
+
.active.item {
|
|
423
|
+
border-bottom: 0.1875rem solid @tertiaryColor !important;
|
|
424
|
+
color: @tertiaryColor !important;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// .tabs-block .ui.menu.RRT__accordion .ui.item .icon {
|
|
430
|
+
// color: #808285;
|
|
431
|
+
// }
|
|
432
|
+
|
|
269
433
|
.loadAddonOverrides();
|
package/src/less/menu.variables
CHANGED
package/src/less/tabs.less
CHANGED
|
@@ -7,6 +7,31 @@
|
|
|
7
7
|
.loadAddonVariables();
|
|
8
8
|
|
|
9
9
|
.tabs-block {
|
|
10
|
+
.tabs-accessibility {
|
|
11
|
+
.ui.button.item:focus-visible {
|
|
12
|
+
outline: 1px dotted #212121 !important;
|
|
13
|
+
outline: 5px auto -webkit-focus-ring-color !important;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
a:focus-visible {
|
|
17
|
+
outline: 1px dotted #212121 !important;
|
|
18
|
+
outline: 5px auto -webkit-focus-ring-color !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.slick-current:focus-visible {
|
|
22
|
+
outline: 1px dotted #212121 !important;
|
|
23
|
+
outline: 5px auto -webkit-focus-ring-color !important;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.accessibility-accordion-tab {
|
|
27
|
+
outline: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.accessibility-accordion-tab:focus-visible {
|
|
31
|
+
outline: 1px dotted #212121 !important;
|
|
32
|
+
outline: 5px auto -webkit-focus-ring-color !important;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
10
35
|
color: @tabsBlockColor;
|
|
11
36
|
|
|
12
37
|
> .styled {
|