@eeacms/volto-eea-design-system 1.19.0 → 1.21.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 +82 -0
- package/cypress.config.js +3 -3
- package/package.json +3 -3
- package/src/ui/Banner/Banner.jsx +7 -13
- package/src/ui/Card/Card.stories.jsx +177 -57
- package/src/ui/Card/Card.stories.test.jsx +206 -0
- package/src/ui/Footer/Footer.jsx +2 -2
- package/src/ui/Header/Header.jsx +71 -71
- package/src/ui/Header/Header.stories.js +58 -51
- package/src/ui/Header/Header.test.jsx +102 -4
- package/src/ui/Header/HeaderMenuPopUp.js +2 -3
- package/src/ui/InpageNavigation/InpageNavigation.jsx +5 -1
- package/src/ui/Item/Item.stories.test.js +2 -2
- package/src/ui/Item/ItemGroupWithIcons.stories.js +28 -18
- package/src/ui/Message/Message.stories.js +6 -6
- package/src/ui/Message/Message.stories.test.js +11 -5
- package/src/ui/Tab/Tab.stories.js +21 -5
- package/src/ui/Tab/Tab.stories.test.js +10 -0
- package/src/ui/TagList/TagList.stories.jsx +1 -1
- package/theme/themes/eea/collections/breadcrumb.overrides +4 -3
- package/theme/themes/eea/collections/menu.overrides +201 -15
- package/theme/themes/eea/collections/menu.variables +43 -28
- package/theme/themes/eea/collections/message.overrides +1 -1
- package/theme/themes/eea/collections/table.overrides +9 -15
- package/theme/themes/eea/elements/button.overrides +2 -2
- package/theme/themes/eea/elements/container.overrides +39 -34
- package/theme/themes/eea/elements/divider.overrides +13 -9
- package/theme/themes/eea/elements/image.overrides +5 -6
- package/theme/themes/eea/elements/label.overrides +16 -16
- package/theme/themes/eea/elements/list.overrides +3 -1
- package/theme/themes/eea/elements/segment.overrides +4 -4
- package/theme/themes/eea/extras/custom.overrides +43 -22
- package/theme/themes/eea/extras/header.less +2 -15
- package/theme/themes/eea/extras/header.variables +1 -3
- package/theme/themes/eea/extras/tag.less +5 -0
- package/theme/themes/eea/extras/tag.variables +1 -1
- package/theme/themes/eea/globals/site.overrides +63 -35
- package/theme/themes/eea/globals/site.variables +2 -5
- package/theme/themes/eea/globals/utilities.less +21 -1
- package/theme/themes/eea/modules/accordion.overrides +36 -24
- package/theme/themes/eea/modules/accordion.variables +4 -4
- package/theme/themes/eea/modules/checkbox.overrides +2 -2
- package/theme/themes/eea/modules/modal.overrides +2 -2
- package/theme/themes/eea/modules/search.overrides +4 -0
- package/theme/themes/eea/modules/tab.overrides +6 -12
- package/theme/themes/eea/modules/tab.variables +2 -1
- package/theme/themes/eea/tokens/colors.less +2 -2
- package/theme/themes/eea/views/card.overrides +50 -35
- package/theme/themes/eea/views/card.variables +7 -2
- package/theme/themes/eea/views/item.overrides +23 -27
- package/theme/themes/eea/views/item.variables +3 -5
- package/theme/themes/eea/views/statistic.overrides +13 -3
|
@@ -1,14 +1,48 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, fireEvent } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
3
4
|
import {
|
|
4
5
|
TeaserCardGrid,
|
|
5
6
|
CarouselCards,
|
|
6
7
|
FluidGrid,
|
|
8
|
+
ImageGrid,
|
|
7
9
|
CardGrid,
|
|
8
10
|
Default,
|
|
9
11
|
} from './Card.stories';
|
|
10
12
|
|
|
11
13
|
describe('TeaserCardGrid component', () => {
|
|
14
|
+
it('renders correctly', () => {
|
|
15
|
+
const { container } = render(<TeaserCardGrid {...TeaserCardGrid.args} />);
|
|
16
|
+
|
|
17
|
+
expect(container.querySelector('.image')).toBeInTheDocument();
|
|
18
|
+
expect(container.querySelector('.header')).toBeInTheDocument();
|
|
19
|
+
expect(container.querySelector('.description')).toBeInTheDocument();
|
|
20
|
+
|
|
21
|
+
expect(
|
|
22
|
+
container.querySelector(`.ui.card.u-card.${TeaserCardGrid.args.variant}`),
|
|
23
|
+
).toBeInTheDocument();
|
|
24
|
+
expect(
|
|
25
|
+
container.querySelector(
|
|
26
|
+
`.ui.card.u-card.max-${TeaserCardGrid.args.maxLines}-lines`,
|
|
27
|
+
),
|
|
28
|
+
).toBeInTheDocument();
|
|
29
|
+
expect(
|
|
30
|
+
container.querySelector(
|
|
31
|
+
`.ui.card.u-card.title-max-${TeaserCardGrid.args.maxLines}-lines`,
|
|
32
|
+
),
|
|
33
|
+
).toBeInTheDocument();
|
|
34
|
+
expect(
|
|
35
|
+
container.querySelector(
|
|
36
|
+
`.ui.card.u-card.has--object-fit--${TeaserCardGrid.args.objectFit}`,
|
|
37
|
+
),
|
|
38
|
+
).toBeInTheDocument();
|
|
39
|
+
expect(
|
|
40
|
+
container.querySelector(
|
|
41
|
+
`.ui.card.u-card.has--object-position--${TeaserCardGrid.args.objectPosition}`,
|
|
42
|
+
),
|
|
43
|
+
).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
|
|
12
46
|
it('renders the teaser card grid with correct number of cards', () => {
|
|
13
47
|
const { container } = render(<TeaserCardGrid {...TeaserCardGrid.args} />);
|
|
14
48
|
const teaserCards = container.querySelectorAll('.column.grid-block-teaser');
|
|
@@ -26,6 +60,39 @@ describe('TeaserCardGrid component', () => {
|
|
|
26
60
|
});
|
|
27
61
|
|
|
28
62
|
describe('CarouselCards component', () => {
|
|
63
|
+
it('renders correctly', () => {
|
|
64
|
+
const { container } = render(<CarouselCards {...CarouselCards.args} />);
|
|
65
|
+
|
|
66
|
+
expect(container.querySelector('.image')).toBeInTheDocument();
|
|
67
|
+
expect(container.querySelector('.header')).toBeInTheDocument();
|
|
68
|
+
expect(container.querySelector('.meta')).toBeInTheDocument();
|
|
69
|
+
expect(container.querySelector('.description')).toBeInTheDocument();
|
|
70
|
+
|
|
71
|
+
expect(
|
|
72
|
+
container.querySelector(`.ui.card.u-card.${CarouselCards.args.variant}`),
|
|
73
|
+
).toBeInTheDocument();
|
|
74
|
+
expect(
|
|
75
|
+
container.querySelector(
|
|
76
|
+
`.ui.card.u-card.max-${CarouselCards.args.maxLines}-lines`,
|
|
77
|
+
),
|
|
78
|
+
).toBeInTheDocument();
|
|
79
|
+
expect(
|
|
80
|
+
container.querySelector(
|
|
81
|
+
`.ui.card.u-card.title-max-${CarouselCards.args.maxLines}-lines`,
|
|
82
|
+
),
|
|
83
|
+
).toBeInTheDocument();
|
|
84
|
+
expect(
|
|
85
|
+
container.querySelector(
|
|
86
|
+
`.ui.card.u-card.has--object-fit--${CarouselCards.args.objectFit}`,
|
|
87
|
+
),
|
|
88
|
+
).toBeInTheDocument();
|
|
89
|
+
expect(
|
|
90
|
+
container.querySelector(
|
|
91
|
+
`.ui.card.u-card.has--object-position--${CarouselCards.args.objectPosition}`,
|
|
92
|
+
),
|
|
93
|
+
).toBeInTheDocument();
|
|
94
|
+
});
|
|
95
|
+
|
|
29
96
|
it('renders the carousel with correct number of cards', () => {
|
|
30
97
|
const { container } = render(<CarouselCards {...CarouselCards.args} />);
|
|
31
98
|
const carouselCards = container.querySelectorAll(
|
|
@@ -46,7 +113,50 @@ describe('CarouselCards component', () => {
|
|
|
46
113
|
});
|
|
47
114
|
});
|
|
48
115
|
|
|
116
|
+
describe('ImageGrid component', () => {
|
|
117
|
+
it('renders the image grid with correct number of cards', () => {
|
|
118
|
+
const { container } = render(<ImageGrid {...ImageGrid.args} />);
|
|
119
|
+
const imageGridCards = container.querySelectorAll(
|
|
120
|
+
'.imageCard-items .ui.card a.image',
|
|
121
|
+
);
|
|
122
|
+
expect(imageGridCards.length).toBe(5);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
49
126
|
describe('FluidGrid component', () => {
|
|
127
|
+
it('renders correctly', () => {
|
|
128
|
+
const { container } = render(<FluidGrid {...FluidGrid.args} />);
|
|
129
|
+
|
|
130
|
+
expect(container.querySelector('.image')).toBeInTheDocument();
|
|
131
|
+
expect(container.querySelector('.header')).toBeInTheDocument();
|
|
132
|
+
expect(container.querySelector('.meta')).toBeInTheDocument();
|
|
133
|
+
expect(container.querySelector('.description')).toBeInTheDocument();
|
|
134
|
+
|
|
135
|
+
expect(
|
|
136
|
+
container.querySelector(`.ui.card.u-card.${FluidGrid.args.variant}`),
|
|
137
|
+
).toBeInTheDocument();
|
|
138
|
+
expect(
|
|
139
|
+
container.querySelector(
|
|
140
|
+
`.ui.card.u-card.max-${FluidGrid.args.maxLines}-lines`,
|
|
141
|
+
),
|
|
142
|
+
).toBeInTheDocument();
|
|
143
|
+
expect(
|
|
144
|
+
container.querySelector(
|
|
145
|
+
`.ui.card.u-card.title-max-${FluidGrid.args.maxLines}-lines`,
|
|
146
|
+
),
|
|
147
|
+
).toBeInTheDocument();
|
|
148
|
+
expect(
|
|
149
|
+
container.querySelector(
|
|
150
|
+
`.ui.card.u-card.has--object-fit--${FluidGrid.args.objectFit}`,
|
|
151
|
+
),
|
|
152
|
+
).toBeInTheDocument();
|
|
153
|
+
expect(
|
|
154
|
+
container.querySelector(
|
|
155
|
+
`.ui.card.u-card.has--object-position--${FluidGrid.args.objectPosition}`,
|
|
156
|
+
),
|
|
157
|
+
).toBeInTheDocument();
|
|
158
|
+
});
|
|
159
|
+
|
|
50
160
|
it('renders fluid grid with correct number of cards', () => {
|
|
51
161
|
const { container } = render(<FluidGrid {...FluidGrid.args} />);
|
|
52
162
|
const fluidGridCards = container.querySelectorAll(
|
|
@@ -58,6 +168,39 @@ describe('FluidGrid component', () => {
|
|
|
58
168
|
});
|
|
59
169
|
|
|
60
170
|
describe('CardGrid component', () => {
|
|
171
|
+
it('renders correctly', () => {
|
|
172
|
+
const { container } = render(<CardGrid {...CardGrid.args} />);
|
|
173
|
+
|
|
174
|
+
expect(container.querySelector('.image')).toBeInTheDocument();
|
|
175
|
+
expect(container.querySelector('.header')).toBeInTheDocument();
|
|
176
|
+
expect(container.querySelector('.meta')).toBeInTheDocument();
|
|
177
|
+
expect(container.querySelector('.description')).toBeInTheDocument();
|
|
178
|
+
|
|
179
|
+
expect(
|
|
180
|
+
container.querySelector(`.ui.card.u-card.${CardGrid.args.variant}`),
|
|
181
|
+
).toBeInTheDocument();
|
|
182
|
+
expect(
|
|
183
|
+
container.querySelector(
|
|
184
|
+
`.ui.card.u-card.max-${CardGrid.args.maxLines}-lines`,
|
|
185
|
+
),
|
|
186
|
+
).toBeInTheDocument();
|
|
187
|
+
expect(
|
|
188
|
+
container.querySelector(
|
|
189
|
+
`.ui.card.u-card.title-max-${CardGrid.args.maxLines}-lines`,
|
|
190
|
+
),
|
|
191
|
+
).toBeInTheDocument();
|
|
192
|
+
expect(
|
|
193
|
+
container.querySelector(
|
|
194
|
+
`.ui.card.u-card.has--object-fit--${CardGrid.args.objectFit}`,
|
|
195
|
+
),
|
|
196
|
+
).toBeInTheDocument();
|
|
197
|
+
expect(
|
|
198
|
+
container.querySelector(
|
|
199
|
+
`.ui.card.u-card.has--object-position--${CardGrid.args.objectPosition}`,
|
|
200
|
+
),
|
|
201
|
+
).toBeInTheDocument();
|
|
202
|
+
});
|
|
203
|
+
|
|
61
204
|
it('renders the card grid with correct number of cards', () => {
|
|
62
205
|
const { container } = render(<CardGrid {...CardGrid.args} />);
|
|
63
206
|
const cardGridCards = container.querySelectorAll(
|
|
@@ -67,7 +210,70 @@ describe('CardGrid component', () => {
|
|
|
67
210
|
});
|
|
68
211
|
});
|
|
69
212
|
|
|
213
|
+
describe('ImageGrid component', () => {
|
|
214
|
+
it('renders correctly', () => {
|
|
215
|
+
const { container } = render(<ImageGrid {...ImageGrid.args} />);
|
|
216
|
+
|
|
217
|
+
expect(container.querySelector('.ui.image')).toBeInTheDocument();
|
|
218
|
+
|
|
219
|
+
expect(
|
|
220
|
+
container.querySelector(`.ui.card.u-card.${ImageGrid.args.variant}`),
|
|
221
|
+
).toBeInTheDocument();
|
|
222
|
+
expect(
|
|
223
|
+
container.querySelector(
|
|
224
|
+
`.ui.card.u-card.has--object-fit--${ImageGrid.args.objectFit}`,
|
|
225
|
+
),
|
|
226
|
+
).toBeInTheDocument();
|
|
227
|
+
expect(
|
|
228
|
+
container.querySelector(
|
|
229
|
+
`.ui.card.u-card.has--object-position--${ImageGrid.args.objectPosition}`,
|
|
230
|
+
),
|
|
231
|
+
).toBeInTheDocument();
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('renders the image grid with correct number of cards', () => {
|
|
235
|
+
const { container } = render(<ImageGrid {...ImageGrid.args} />);
|
|
236
|
+
const imageGridCards = container.querySelectorAll(
|
|
237
|
+
'.ui.card.u-card.default .ui.image',
|
|
238
|
+
);
|
|
239
|
+
expect(imageGridCards.length).toBe(5);
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
70
243
|
describe('Default component', () => {
|
|
244
|
+
it('renders correctly', () => {
|
|
245
|
+
const { container } = render(<Default {...Default.args} />);
|
|
246
|
+
|
|
247
|
+
expect(container.querySelector('.image')).toBeInTheDocument();
|
|
248
|
+
expect(container.querySelector('.header')).toBeInTheDocument();
|
|
249
|
+
expect(container.querySelector('.meta')).toBeInTheDocument();
|
|
250
|
+
expect(container.querySelector('.description')).toBeInTheDocument();
|
|
251
|
+
|
|
252
|
+
expect(
|
|
253
|
+
container.querySelector(`.ui.card.u-card.${Default.args.variant}`),
|
|
254
|
+
).toBeInTheDocument();
|
|
255
|
+
expect(
|
|
256
|
+
container.querySelector(
|
|
257
|
+
`.ui.card.u-card.max-${Default.args.maxLines}-lines`,
|
|
258
|
+
),
|
|
259
|
+
).toBeInTheDocument();
|
|
260
|
+
expect(
|
|
261
|
+
container.querySelector(
|
|
262
|
+
`.ui.card.u-card.title-max-${Default.args.maxLines}-lines`,
|
|
263
|
+
),
|
|
264
|
+
).toBeInTheDocument();
|
|
265
|
+
expect(
|
|
266
|
+
container.querySelector(
|
|
267
|
+
`.ui.card.u-card.has--object-fit--${Default.args.objectFit}`,
|
|
268
|
+
),
|
|
269
|
+
).toBeInTheDocument();
|
|
270
|
+
expect(
|
|
271
|
+
container.querySelector(
|
|
272
|
+
`.ui.card.u-card.has--object-position--${Default.args.objectPosition}`,
|
|
273
|
+
),
|
|
274
|
+
).toBeInTheDocument();
|
|
275
|
+
});
|
|
276
|
+
|
|
71
277
|
it('renders the default with correct number of cards', () => {
|
|
72
278
|
const { container } = render(<Default {...Default.args} />);
|
|
73
279
|
const defaultCards = container.querySelectorAll(
|
package/src/ui/Footer/Footer.jsx
CHANGED
|
@@ -18,7 +18,7 @@ import Description from '@eeacms/volto-eea-design-system/ui/Footer/Description';
|
|
|
18
18
|
/**
|
|
19
19
|
* Component to display the footer.
|
|
20
20
|
* @function Footer
|
|
21
|
-
* @param {Object}
|
|
21
|
+
* @param {Object} props object
|
|
22
22
|
* @returns {string} Markup of the component
|
|
23
23
|
*/
|
|
24
24
|
|
|
@@ -28,7 +28,7 @@ const Footer = (props) => {
|
|
|
28
28
|
const bgImgRef = React.useRef();
|
|
29
29
|
const onScreen = useFirstVisited(bgImgRef);
|
|
30
30
|
return (
|
|
31
|
-
<footer id={'footer'}>
|
|
31
|
+
<footer id={'footer'} aria-label={'Footer'}>
|
|
32
32
|
<div
|
|
33
33
|
ref={bgImgRef}
|
|
34
34
|
className={onScreen ? 'footer-wrapper' : 'footer-wrapper-nobg'}
|
package/src/ui/Header/Header.jsx
CHANGED
|
@@ -15,7 +15,7 @@ import burgerIcon from '@eeacms/volto-eea-design-system/../theme/themes/eea/asse
|
|
|
15
15
|
import HeaderSearchPopUp from './HeaderSearchPopUp';
|
|
16
16
|
import HeaderMenuPopUp from './HeaderMenuPopUp';
|
|
17
17
|
import PropTypes from 'prop-types';
|
|
18
|
-
|
|
18
|
+
import _ from 'lodash';
|
|
19
19
|
import { isInternalURL } from '@plone/volto/helpers';
|
|
20
20
|
import config from '@plone/volto/registry';
|
|
21
21
|
|
|
@@ -25,7 +25,11 @@ Header.propTypes = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
function Header({ children }) {
|
|
28
|
-
return
|
|
28
|
+
return (
|
|
29
|
+
<header className="eea header" aria-label={'Site'}>
|
|
30
|
+
{children}
|
|
31
|
+
</header>
|
|
32
|
+
);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
const TopHeader = ({ children }) => (
|
|
@@ -44,15 +48,15 @@ const onKeyDownHandler = (event) => {
|
|
|
44
48
|
if (event.key === 'Enter') {
|
|
45
49
|
event.preventDefault();
|
|
46
50
|
event.target.click();
|
|
47
|
-
//event.target.focus();
|
|
48
51
|
}
|
|
49
52
|
};
|
|
50
53
|
|
|
51
54
|
const TopDropdownMenu = ({
|
|
52
55
|
children,
|
|
56
|
+
ariaLabel,
|
|
53
57
|
className,
|
|
58
|
+
classNameHeader,
|
|
54
59
|
icon,
|
|
55
|
-
hasLanguageDropdown = false,
|
|
56
60
|
id,
|
|
57
61
|
tabletText,
|
|
58
62
|
mobileText,
|
|
@@ -63,45 +67,38 @@ const TopDropdownMenu = ({
|
|
|
63
67
|
const isMobile = viewportWidth < 767;
|
|
64
68
|
|
|
65
69
|
const Component = ({ mobileText }) => {
|
|
70
|
+
const headerText = mobileText || text;
|
|
71
|
+
const label = ariaLabel || headerText;
|
|
72
|
+
const dropdownRef = React.useRef(null);
|
|
73
|
+
|
|
66
74
|
return (
|
|
67
75
|
<>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
aria-label="dropdown"
|
|
95
|
-
lazyLoad
|
|
96
|
-
closeOnChange={true}
|
|
97
|
-
closeOnBlur={false}
|
|
98
|
-
closeOnEscape={true}
|
|
99
|
-
openOnFocus={false}
|
|
100
|
-
onKeyDown={onKeyDownHandler}
|
|
101
|
-
>
|
|
102
|
-
<Dropdown.Menu role="option">{children}</Dropdown.Menu>
|
|
103
|
-
</Dropdown>
|
|
104
|
-
)}
|
|
76
|
+
<Dropdown
|
|
77
|
+
id={id}
|
|
78
|
+
className={className}
|
|
79
|
+
text={() => (
|
|
80
|
+
<div className={`divider text ${classNameHeader}`}>
|
|
81
|
+
{headerText}
|
|
82
|
+
</div>
|
|
83
|
+
)}
|
|
84
|
+
ref={dropdownRef}
|
|
85
|
+
icon={icon || 'chevron down'}
|
|
86
|
+
aria-label={label}
|
|
87
|
+
closeOnChange={true}
|
|
88
|
+
closeOnBlur={false}
|
|
89
|
+
closeOnEscape={true}
|
|
90
|
+
openOnFocus={true}
|
|
91
|
+
onBlur={(e) => {
|
|
92
|
+
const dropdown = dropdownRef.current;
|
|
93
|
+
const ref = dropdown.ref.current;
|
|
94
|
+
if (e.target !== ref && !ref.contains(e.relatedTarget)) {
|
|
95
|
+
dropdown.close();
|
|
96
|
+
}
|
|
97
|
+
}}
|
|
98
|
+
onKeyDown={onKeyDownHandler}
|
|
99
|
+
>
|
|
100
|
+
<Dropdown.Menu role="option">{children}</Dropdown.Menu>
|
|
101
|
+
</Dropdown>
|
|
105
102
|
</>
|
|
106
103
|
);
|
|
107
104
|
};
|
|
@@ -288,7 +285,7 @@ const Main = ({
|
|
|
288
285
|
className={`main bar ${transparency ? 'transparency' : ''}`}
|
|
289
286
|
ref={node}
|
|
290
287
|
>
|
|
291
|
-
<Container>
|
|
288
|
+
<Container className={'main-bar-container'}>
|
|
292
289
|
<Grid>
|
|
293
290
|
<Grid.Column mobile={8} tablet={8} computer={4}>
|
|
294
291
|
{logo}
|
|
@@ -296,52 +293,57 @@ const Main = ({
|
|
|
296
293
|
<Grid.Column mobile={4} tablet={4} computer={8}>
|
|
297
294
|
<div className={inverted ? 'main-menu inverted' : 'main-menu'}>
|
|
298
295
|
{menuItems && (
|
|
299
|
-
<
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
296
|
+
<nav aria-label={'Main'}>
|
|
297
|
+
<ul
|
|
298
|
+
className="ui text eea-main-menu tablet or lower hidden menu"
|
|
299
|
+
ref={desktopMenuRef}
|
|
300
|
+
id={'navigation'}
|
|
301
|
+
>
|
|
302
|
+
{menuItems.map((item) => (
|
|
303
|
+
<Menu.Item
|
|
304
|
+
name={item['@id'] || item.url}
|
|
305
|
+
key={item['@id'] || item.url}
|
|
306
|
+
as={'li'}
|
|
307
|
+
active={
|
|
308
|
+
activeItem.indexOf(item['@id']) !== -1 ||
|
|
309
|
+
activeItem.indexOf(item.url) !== -1
|
|
310
|
+
}
|
|
311
|
+
aria-expanded={
|
|
312
|
+
activeItem.indexOf(item['@id']) !== -1 ||
|
|
313
|
+
activeItem.indexOf(item.url) !== -1
|
|
314
|
+
}
|
|
315
|
+
>
|
|
316
|
+
{renderGlobalMenuItem(item, {
|
|
317
|
+
onClick: menuOnClick,
|
|
318
|
+
})}
|
|
319
|
+
</Menu.Item>
|
|
320
|
+
))}
|
|
321
|
+
</ul>
|
|
322
|
+
</nav>
|
|
320
323
|
)}
|
|
321
324
|
{!hideSearch && (
|
|
322
325
|
<button
|
|
323
326
|
className="search-action"
|
|
324
327
|
onClick={searchOnClick}
|
|
325
|
-
|
|
326
|
-
aria-pressed="false"
|
|
327
|
-
aria-haspopup="true"
|
|
328
|
+
aria-expanded={searchIsActive}
|
|
328
329
|
ref={searchButtonRef}
|
|
329
330
|
>
|
|
330
331
|
{/* <Icon name={!state.activeSearch ? 'search' : 'close'} /> */}
|
|
331
332
|
<Image
|
|
332
333
|
src={!searchIsActive ? `${searchIcon}` : `${closeIcon}`}
|
|
333
|
-
alt="search
|
|
334
|
+
alt="Global search"
|
|
334
335
|
/>
|
|
335
336
|
</button>
|
|
336
337
|
)}
|
|
337
338
|
<Header.BurgerAction
|
|
338
339
|
className={`mobile ${burger}`}
|
|
339
340
|
onClick={mobileBurgerOnClick}
|
|
341
|
+
aria-expanded={menuIsActive}
|
|
340
342
|
ref={mobileMenuBurgerRef}
|
|
341
343
|
>
|
|
342
344
|
<Image
|
|
343
345
|
src={burger === 'open' ? `${closeIcon}` : `${burgerIcon}`}
|
|
344
|
-
alt="
|
|
346
|
+
alt="Menu navigation"
|
|
345
347
|
/>
|
|
346
348
|
</Header.BurgerAction>
|
|
347
349
|
</div>
|
|
@@ -374,9 +376,7 @@ const BurgerAction = React.forwardRef((props, ref) => (
|
|
|
374
376
|
<button
|
|
375
377
|
ref={ref}
|
|
376
378
|
className={`burger-action ${props.className}`}
|
|
377
|
-
|
|
378
|
-
aria-pressed="false"
|
|
379
|
-
aria-haspopup="true"
|
|
379
|
+
{..._.omit(props, ['onClick', 'children', 'className', 'ref'])}
|
|
380
380
|
onClick={props.onClick}
|
|
381
381
|
>
|
|
382
382
|
{props.children}
|
|
@@ -58,16 +58,20 @@ const logoProps = {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
const links = [
|
|
61
|
-
{ title: '
|
|
62
|
-
{ title: '
|
|
63
|
-
{
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
{ title: 'European Environment Agency website', href: '/#' },
|
|
62
|
+
{ title: 'WISE marine - Marine information system for Europe', href: '/#' },
|
|
63
|
+
{
|
|
64
|
+
title: 'WISE freshwater - Freshwater information system for Europe',
|
|
65
|
+
href: '/#',
|
|
66
|
+
},
|
|
67
|
+
{ title: 'BISE - Biodiversity information system for Europe', href: '/#' },
|
|
68
|
+
{ title: 'FISE - Forest information system for Europe', href: '/#' },
|
|
69
|
+
{ title: 'European Climate and health observatory', href: '/#' },
|
|
70
|
+
{ title: 'ClimateADAPT', href: '/#' },
|
|
66
71
|
{ title: 'European Industrial Emissions Portal', href: '/#' },
|
|
67
|
-
{ title: '
|
|
68
|
-
{ title: '
|
|
69
|
-
{ title: '
|
|
70
|
-
{ title: 'Fresh Water Information System for Europe', href: '/#' },
|
|
72
|
+
{ title: 'Climate and Energy in the EU', href: '/#' },
|
|
73
|
+
{ title: 'Copernicus Land Monitoring Service', href: '/#' },
|
|
74
|
+
{ title: 'Copernicus InSitu', href: '/#' },
|
|
71
75
|
];
|
|
72
76
|
|
|
73
77
|
const languages = [
|
|
@@ -1234,7 +1238,7 @@ const Template = (args) => {
|
|
|
1234
1238
|
<Header>
|
|
1235
1239
|
<Header.TopHeader>
|
|
1236
1240
|
<Header.TopItem className="official-union">
|
|
1237
|
-
<Image src={eeaFlag} alt="
|
|
1241
|
+
<Image src={eeaFlag} alt="European Union flag"></Image>
|
|
1238
1242
|
<Header.TopDropdownMenu
|
|
1239
1243
|
text="An official website of the European Union | How do you know?"
|
|
1240
1244
|
tabletText="An official website of the European Union"
|
|
@@ -1242,6 +1246,7 @@ const Template = (args) => {
|
|
|
1242
1246
|
icon="chevron down"
|
|
1243
1247
|
aria-label="dropdown"
|
|
1244
1248
|
className=""
|
|
1249
|
+
classNameHeader="mobile-sr-only"
|
|
1245
1250
|
viewportWidth={viewportWidth}
|
|
1246
1251
|
>
|
|
1247
1252
|
<div
|
|
@@ -1276,7 +1281,7 @@ const Template = (args) => {
|
|
|
1276
1281
|
mobileText={mobileLinksMenuTitle}
|
|
1277
1282
|
viewportWidth={viewportWidth}
|
|
1278
1283
|
>
|
|
1279
|
-
<div className="wrapper">
|
|
1284
|
+
<div className="wrapper" tabIndex={0} role={'presentation'}>
|
|
1280
1285
|
{links.map((item, index) => (
|
|
1281
1286
|
<Dropdown.Item key={index}>
|
|
1282
1287
|
<a
|
|
@@ -1293,47 +1298,49 @@ const Template = (args) => {
|
|
|
1293
1298
|
</Header.TopDropdownMenu>
|
|
1294
1299
|
</Header.TopItem>
|
|
1295
1300
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
<ul
|
|
1312
|
-
className="wrapper language-list"
|
|
1313
|
-
role="listbox"
|
|
1314
|
-
aria-label="language switcher"
|
|
1301
|
+
{hasLanguageDropdown && (
|
|
1302
|
+
<Header.TopDropdownMenu
|
|
1303
|
+
id="language-switcher"
|
|
1304
|
+
className="item"
|
|
1305
|
+
ariaLabel={'language switcher'}
|
|
1306
|
+
text={`${language.toUpperCase()}`}
|
|
1307
|
+
mobileText={`${language.toUpperCase()}`}
|
|
1308
|
+
icon={
|
|
1309
|
+
<Image
|
|
1310
|
+
role="option"
|
|
1311
|
+
src={globeIcon}
|
|
1312
|
+
alt="language dropdown globe icon"
|
|
1313
|
+
></Image>
|
|
1314
|
+
}
|
|
1315
|
+
viewportWidth={viewportWidth}
|
|
1315
1316
|
>
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
{
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1317
|
+
<ul
|
|
1318
|
+
className="wrapper language-list"
|
|
1319
|
+
role="listbox"
|
|
1320
|
+
aria-label="language switcher"
|
|
1321
|
+
>
|
|
1322
|
+
{languages.map((item, index) => (
|
|
1323
|
+
<Dropdown.Item
|
|
1324
|
+
as="li"
|
|
1325
|
+
key={index}
|
|
1326
|
+
text={
|
|
1327
|
+
<a
|
|
1328
|
+
href={'/' + item.code}
|
|
1329
|
+
onClick={() => setLanguage(item.code)}
|
|
1330
|
+
tabIndex={0}
|
|
1331
|
+
className={'language-link'}
|
|
1332
|
+
>
|
|
1333
|
+
{item.name}
|
|
1334
|
+
<span className="country-code">
|
|
1335
|
+
{item.code.toUpperCase()}
|
|
1336
|
+
</span>
|
|
1337
|
+
</a>
|
|
1338
|
+
}
|
|
1339
|
+
></Dropdown.Item>
|
|
1340
|
+
))}
|
|
1341
|
+
</ul>
|
|
1342
|
+
</Header.TopDropdownMenu>
|
|
1343
|
+
)}
|
|
1337
1344
|
</Header.TopHeader>
|
|
1338
1345
|
<Header.Main
|
|
1339
1346
|
transparency={args.transparency}
|