@eeacms/volto-n2k 0.1.5 → 0.1.8

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 CHANGED
@@ -4,10 +4,32 @@ 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
+ #### [0.1.8](https://github.com/eea/volto-n2k/compare/0.1.7...0.1.8)
8
+
9
+ - update [`8ed8e64`](https://github.com/eea/volto-n2k/commit/8ed8e641a64fa24675aac34a3b774f6c8d7da67c)
10
+ - Set toolkit link [`a8e42f5`](https://github.com/eea/volto-n2k/commit/a8e42f56717d022c1b978c89a8276d98fb525b74)
11
+ - Change style for arrows and dots in carousel [`09baad7`](https://github.com/eea/volto-n2k/commit/09baad72af985d7895cfd250fec40db8f3748dc5)
12
+
13
+ #### [0.1.7](https://github.com/eea/volto-n2k/compare/0.1.6...0.1.7)
14
+
15
+ > 3 August 2022
16
+
17
+ - Update links [`#8`](https://github.com/eea/volto-n2k/pull/8)
18
+ - Update toolkit link [`d791e63`](https://github.com/eea/volto-n2k/commit/d791e63603d750afbead921f1cebbf90902dc8e2)
19
+ - Change link for natura2000 [`98fb51c`](https://github.com/eea/volto-n2k/commit/98fb51c76320ac47e6bbeb0e4012cc49932c17d2)
20
+
21
+ #### [0.1.6](https://github.com/eea/volto-n2k/compare/0.1.5...0.1.6)
22
+
23
+ > 3 August 2022
24
+
25
+ - Add toolkit in landing page [`#7`](https://github.com/eea/volto-n2k/pull/7)
26
+
7
27
  #### [0.1.5](https://github.com/eea/volto-n2k/compare/0.1.4...0.1.5)
8
28
 
29
+ > 28 July 2022
30
+
31
+ - Show language native name [`#6`](https://github.com/eea/volto-n2k/pull/6)
9
32
  - Use volto 16 for cypress tests [`dfb57d1`](https://github.com/eea/volto-n2k/commit/dfb57d12d37dbeb1aa8c0d87cf8cc950cdf27d13)
10
- - Show language native name [`20692d7`](https://github.com/eea/volto-n2k/commit/20692d74fb65ff686d23e73bd87d676b871b266f)
11
33
 
12
34
  #### [0.1.4](https://github.com/eea/volto-n2k/compare/0.1.3...0.1.4)
13
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-n2k",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "volto-n2k: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -0,0 +1,202 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import { compose } from 'redux';
4
+ import { withRouter } from 'react-router';
5
+ import loadable from '@loadable/component';
6
+ import cx from 'classnames';
7
+ import { Icon, RenderBlocks } from '@plone/volto/components';
8
+ import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
9
+
10
+ import rightArrowSVG from '@eeacms/volto-n2k/icons/right-key.svg';
11
+ import leftArrowSVG from '@eeacms/volto-n2k/icons/left-key.svg';
12
+
13
+ import 'slick-carousel/slick/slick.css';
14
+ import 'slick-carousel/slick/slick-theme.css';
15
+ import '@eeacms/volto-tabs-block/less/carousel.less';
16
+
17
+ const Slider = loadable(() => import('react-slick'));
18
+
19
+ const Dots = (props) => {
20
+ const { activeTab = null, tabsList = [], slider = {} } = props;
21
+ return tabsList.length > 1 ? (
22
+ <div className="slick-dots-wrapper">
23
+ <div className="slick-line" />
24
+ <ul className={cx('slick-dots ui container', props.uiContainer)}>
25
+ {tabsList.map((tab, index) => (
26
+ <li
27
+ key={`dot-${tab}`}
28
+ className={cx({ 'slick-active': activeTab === tab })}
29
+ >
30
+ <button
31
+ aria-label={`Select slide ${index + 1}`}
32
+ onClick={() => {
33
+ if (slider.current) {
34
+ slider.current.slickGoTo(index);
35
+ }
36
+ }}
37
+ />
38
+ </li>
39
+ ))}
40
+ </ul>
41
+ </div>
42
+ ) : (
43
+ ''
44
+ );
45
+ };
46
+
47
+ const ArrowsGroup = (props) => {
48
+ const { activeTab = null, tabsList = [], slider = {} } = props;
49
+ const currentSlide = tabsList.indexOf(activeTab);
50
+ const slideCount = tabsList.length;
51
+
52
+ return (
53
+ <div
54
+ className={cx({
55
+ 'slick-arrows': true,
56
+ 'one-arrow': currentSlide === 0 || currentSlide === slideCount - 1,
57
+ })}
58
+ >
59
+ {currentSlide > 0 ? (
60
+ <button
61
+ aria-label="Previous slide"
62
+ className="slick-arrow slick-prev"
63
+ onClick={() => {
64
+ if (slider.current) {
65
+ slider.current.slickPrev();
66
+ }
67
+ }}
68
+ >
69
+ <Icon name={leftArrowSVG} size="50px" />
70
+ </button>
71
+ ) : (
72
+ ''
73
+ )}
74
+ {currentSlide < slideCount - 1 ? (
75
+ <button
76
+ aria-label="Next slide"
77
+ className="slick-arrow slick-next"
78
+ onClick={() => {
79
+ if (slider.current) {
80
+ slider.current.slickNext();
81
+ }
82
+ }}
83
+ >
84
+ <Icon name={rightArrowSVG} size="50px" />
85
+ </button>
86
+ ) : (
87
+ ''
88
+ )}
89
+ </div>
90
+ );
91
+ };
92
+
93
+ const View = (props) => {
94
+ const slider = React.useRef(null);
95
+ const [hashlinkOnMount, setHashlinkOnMount] = React.useState(false);
96
+ const {
97
+ activeTab = null,
98
+ data = {},
99
+ hashlink = {},
100
+ metadata = {},
101
+ tabsList = [],
102
+ tabs = {},
103
+ setActiveTab = () => {},
104
+ } = props;
105
+ const activeTabIndex = tabsList.indexOf(activeTab);
106
+ const uiContainer = data.align === 'full' ? 'ui container' : false;
107
+
108
+ const settings = {
109
+ autoplay: false,
110
+ arrows: false,
111
+ dots: false,
112
+ speed: 500,
113
+ initialSlide: 0,
114
+ lazyLoad: 'ondemand',
115
+ swipe: true,
116
+ slidesToShow: 1,
117
+ slidesToScroll: 1,
118
+ touchMove: true,
119
+ beforeChange: (oldIndex, index) => {
120
+ setActiveTab(tabsList[index]);
121
+ },
122
+ };
123
+
124
+ React.useEffect(() => {
125
+ if (!slider.current?.innerSlider?.list) return;
126
+ const unfocuseElements = ['a', 'button', 'input'];
127
+ unfocuseElements.forEach((tag) => {
128
+ for (let element of slider.current.innerSlider.list.querySelectorAll(
129
+ ".slick-slide[aria-hidden='true'] a",
130
+ )) {
131
+ element.setAttribute('aria-hiden', 'true');
132
+ }
133
+ });
134
+ }, [activeTab]);
135
+
136
+ React.useEffect(() => {
137
+ const urlHash = props.location.hash.substring(1) || '';
138
+ if (
139
+ hashlink.counter > 0 ||
140
+ (hashlink.counter === 0 && urlHash && !hashlinkOnMount)
141
+ ) {
142
+ const id = hashlink.hash || urlHash || '';
143
+ const index = tabsList.indexOf(id);
144
+ const parentId = data.id || props.id;
145
+ const parent = document.getElementById(parentId);
146
+ // TODO: Find the best way to add offset relative to header
147
+ // The header can be static on mobile and relative on > mobile
148
+ const headerWrapper = document.querySelector('.header-wrapper');
149
+ const offsetHeight = headerWrapper?.offsetHeight || 0;
150
+ if (
151
+ id !== parentId &&
152
+ parentId === hashlink.data.parentId &&
153
+ index > -1 &&
154
+ parent
155
+ ) {
156
+ if (activeTabIndex !== index) {
157
+ slider.current.slickGoTo(index);
158
+ }
159
+ props.scrollToTarget(parent, offsetHeight);
160
+ } else if (id === parentId && parent) {
161
+ props.scrollToTarget(parent, offsetHeight);
162
+ }
163
+ }
164
+ if (!hashlinkOnMount) {
165
+ setHashlinkOnMount(true);
166
+ }
167
+ /* eslint-disable-next-line */
168
+ }, [hashlink.counter]);
169
+
170
+ const panes = tabsList.map((tab, index) => {
171
+ return {
172
+ id: tab,
173
+ renderItem: (
174
+ <RenderBlocks
175
+ key={`slide-${tab}`}
176
+ {...props}
177
+ metadata={metadata}
178
+ content={tabs[tab]}
179
+ />
180
+ ),
181
+ };
182
+ });
183
+
184
+ return (
185
+ <>
186
+ <Slider {...settings} ref={slider} className={cx(uiContainer)}>
187
+ {panes.length ? panes.map((pane) => pane.renderItem) : ''}
188
+ </Slider>
189
+ <ArrowsGroup activeTab={activeTab} tabsList={tabsList} slider={slider} />
190
+ <Dots activeTab={activeTab} tabsList={tabsList} slider={slider} />
191
+ </>
192
+ );
193
+ };
194
+
195
+ export default compose(
196
+ connect((state) => {
197
+ return {
198
+ hashlink: state.hashlink,
199
+ };
200
+ }),
201
+ withScrollToTarget,
202
+ )(withRouter(View));
@@ -5,8 +5,8 @@ import { withRouter } from 'react-router';
5
5
  import loadable from '@loadable/component';
6
6
  import { Icon, RenderBlocks } from '@plone/volto/components';
7
7
  import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
8
- import rightArrowSVG from '@eeacms/volto-tabs-block/icons/right-arrow.svg';
9
- import leftArrowSVG from '@eeacms/volto-tabs-block/icons/left-arrow.svg';
8
+ import rightArrowSVG from '@eeacms/volto-n2k/icons/right-key.svg';
9
+ import leftArrowSVG from '@eeacms/volto-n2k/icons/left-key.svg';
10
10
  import cx from 'classnames';
11
11
  import 'slick-carousel/slick/slick.css';
12
12
  import 'slick-carousel/slick/slick-theme.css';
@@ -1,3 +1,4 @@
1
+ import DefaultHorizontalView from './DefaultHorizontalView';
1
2
  import HorizontalCarouselView from './HorizontalView';
2
3
  import carouselSchema from './schema';
3
4
 
@@ -8,6 +9,10 @@ export default (config) => {
8
9
  ...(config.blocks.blocksConfig.tabs_block || {}),
9
10
  templates: {
10
11
  ...(config.blocks.blocksConfig.tabs_block?.templates || {}),
12
+ carousel: {
13
+ ...(config.blocks.blocksConfig.tabs_block?.templates?.carousel || {}),
14
+ view: DefaultHorizontalView,
15
+ },
11
16
  carousel_n2k: {
12
17
  title: 'Carousel Natura 2000',
13
18
  view: HorizontalCarouselView,
@@ -6,7 +6,7 @@ import forests from './images/forests.webp';
6
6
  import mountains from './images/mountains.webp';
7
7
  import grasslands from './images/grasslands.webp';
8
8
  import rivers from './images/rivers.webp';
9
- import islands from './images/islands.webp';
9
+ import toolkit from './images/toolkit_icon.webp';
10
10
  import peatlands from './images/peatlands.webp';
11
11
  import natura2000 from './images/natura2000.webp';
12
12
 
@@ -54,10 +54,11 @@ export const tiles = [
54
54
  link: '/natura2000/:lang/rivers-and-lakes',
55
55
  },
56
56
  {
57
- image: islands,
58
- title: 'Islands',
59
- description: 'ISLANDS',
60
- link: '/natura2000/:lang/islands',
57
+ image: toolkit,
58
+ title: 'Toolkit',
59
+ description: 'TOOLKIT',
60
+ link:
61
+ 'https://op.europa.eu/fr/publication-detail/:lang/publication/e33a1119-8fa2-11ec-8c40-01aa75ed71a1',
61
62
  },
62
63
  ];
63
64
 
@@ -123,7 +123,7 @@ const CopyPaste = (props) => {
123
123
  onMouseEnter={(e) => {
124
124
  if (
125
125
  e.altKey &&
126
- e.ctrlKey &&
126
+ e.shiftKey &&
127
127
  toolbar.current &&
128
128
  !toolbar.current.classList.contains('__dev_on')
129
129
  ) {
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
4
+ <!-- Generator: Sketch Beta 3.3.2 (12041) - http://www.bohemiancoding.com/sketch -->
5
+ <title>arrow-left-circle</title>
6
+ <desc>Created with Sketch Beta.</desc>
7
+ <defs></defs>
8
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
9
+ <g id="Icon-Set-Filled" sketch:type="MSLayerGroup" transform="translate(-258.000000, -1089.000000)"
10
+ fill="#ffffff">
11
+ <path
12
+ d="M281,1106 L270.414,1106 L274.536,1110.12 C274.926,1110.51 274.926,1111.15 274.536,1111.54 C274.145,1111.93 273.512,1111.93 273.121,1111.54 L267.464,1105.88 C267.225,1105.64 267.15,1105.31 267.205,1105 C267.15,1104.69 267.225,1104.36 267.464,1104.12 L273.121,1098.46 C273.512,1098.07 274.145,1098.07 274.536,1098.46 C274.926,1098.86 274.926,1099.49 274.536,1099.88 L270.414,1104 L281,1104 C281.552,1104 282,1104.45 282,1105 C282,1105.55 281.552,1106 281,1106 L281,1106 Z M274,1089 C265.164,1089 258,1096.16 258,1105 C258,1113.84 265.164,1121 274,1121 C282.836,1121 290,1113.84 290,1105 C290,1096.16 282.836,1089 274,1089 L274,1089 Z"
13
+ id="arrow-left-circle" sketch:type="MSShapeGroup"></path>
14
+ </g>
15
+ </g>
16
+ </svg>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"
3
+ xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
4
+ <!-- Generator: Sketch Beta 3.3.2 (12041) - http://www.bohemiancoding.com/sketch -->
5
+ <title>arrow-right-circle</title>
6
+ <desc>Created with Sketch Beta.</desc>
7
+ <defs></defs>
8
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
9
+ <g id="Icon-Set-Filled" sketch:type="MSLayerGroup" transform="translate(-310.000000, -1089.000000)"
10
+ fill="#ffffff">
11
+ <path
12
+ d="M332.535,1105.88 L326.879,1111.54 C326.488,1111.93 325.855,1111.93 325.465,1111.54 C325.074,1111.15 325.074,1110.51 325.465,1110.12 L329.586,1106 L319,1106 C318.447,1106 318,1105.55 318,1105 C318,1104.45 318.447,1104 319,1104 L329.586,1104 L325.465,1099.88 C325.074,1099.49 325.074,1098.86 325.465,1098.46 C325.855,1098.07 326.488,1098.07 326.879,1098.46 L332.535,1104.12 C332.775,1104.36 332.85,1104.69 332.795,1105 C332.85,1105.31 332.775,1105.64 332.535,1105.88 L332.535,1105.88 Z M326,1089 C317.163,1089 310,1096.16 310,1105 C310,1113.84 317.163,1121 326,1121 C334.837,1121 342,1113.84 342,1105 C342,1096.16 334.837,1089 326,1089 L326,1089 Z"
13
+ id="arrow-right-circle" sketch:type="MSShapeGroup"></path>
14
+ </g>
15
+ </g>
16
+ </svg>
@@ -590,27 +590,6 @@ img.slick-image {
590
590
  padding: 0.5rem;
591
591
  }
592
592
 
593
- @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
594
- img.slick-image {
595
- left: -200px;
596
- width: 550px;
597
- }
598
- }
599
-
600
- @media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) {
601
- img.slick-image {
602
- left: -200px;
603
- width: 650px;
604
- }
605
- }
606
-
607
- @media only screen and (min-width: @largeMonitorBreakpoint) {
608
- img.slick-image {
609
- left: -150px;
610
- width: 650px;
611
- }
612
- }
613
-
614
593
  .n2k-green-border {
615
594
  .block.maps {
616
595
  > div {
@@ -689,3 +668,138 @@ img.slick-image {
689
668
  .dark-green-background {
690
669
  background-color: #04a87d;
691
670
  }
671
+
672
+ .tabs-block .slick-slider {
673
+ order: 1;
674
+ }
675
+
676
+ .tabs-block .slick-arrow {
677
+ order: 2;
678
+ }
679
+
680
+ .tabs-block .slick-dots-wrapper {
681
+ order: 3;
682
+ }
683
+
684
+ .tabs-block .slick-dots-wrapper .slick-dots li {
685
+ width: 20px;
686
+ height: 20px;
687
+ }
688
+
689
+ .tabs-block .slick-dots-wrapper .slick-dots li button {
690
+ width: 20px;
691
+ height: 20px;
692
+ box-shadow: 0 0px 10px rgba(0, 0, 0, 0.3);
693
+ }
694
+
695
+ .tabs-block .slick-dots-wrapper .slick-dots li.slick-active::before {
696
+ // display: none;
697
+ top: -9px;
698
+ left: -9px;
699
+ width: calc(20px + 2 * 9px);
700
+ height: calc(20px + 2 * 9px);
701
+ }
702
+
703
+ .tabs-block .slick-dots-wrapper .slick-dots li.slick-active button {
704
+ border-color: #3b7f02;
705
+ background-color: #3b7f02 !important;
706
+ }
707
+
708
+ .tabs-block.light .slick-dots-wrapper .slick-dots li.slick-active::before {
709
+ border: 3px solid #fff;
710
+ }
711
+
712
+ .tabs-block.grey .slick-dots-wrapper .slick-dots li.slick-active::before {
713
+ border: 3px solid #b3b3b3;
714
+ }
715
+
716
+ .tabs-block.dark .slick-dots-wrapper .slick-dots li.slick-active::before {
717
+ border: 3px solid #000;
718
+ }
719
+
720
+ .tabs-block.light .slick-dots-wrapper .slick-dots li button {
721
+ border: 2px solid #fff;
722
+ }
723
+
724
+ .tabs-block .slick-arrows button.slick-arrow {
725
+ display: flex !important;
726
+ align-items: center;
727
+ }
728
+
729
+ .tabs-block.light .slick-arrows button.slick-arrow svg {
730
+ fill: #fff;
731
+
732
+ path {
733
+ fill: #fff;
734
+ }
735
+ }
736
+
737
+ .tabs-block.grey .slick-arrows button.slick-arrow svg {
738
+ fill: #b3b3b3;
739
+
740
+ path {
741
+ fill: #b3b3b3;
742
+ }
743
+ }
744
+
745
+ .tabs-block.dark .slick-arrows button.slick-arrow svg {
746
+ fill: #000;
747
+
748
+ path {
749
+ fill: #000;
750
+ }
751
+ }
752
+
753
+ .tabs-block.carousel_n2k .slick-arrows .learn-more {
754
+ margin-bottom: 0 !important;
755
+ }
756
+
757
+ @media only screen and (max-width: @largestTabletScreen) {
758
+ .tabs-block .slick-slider {
759
+ order: 2;
760
+
761
+ .slick-slide {
762
+ padding-top: 0 !important;
763
+ }
764
+ }
765
+
766
+ .tabs-block .slick-arrows {
767
+ justify-content: end;
768
+ order: 1;
769
+ padding: 1rem;
770
+ }
771
+
772
+ .tabs-block .slick-dots-wrapper {
773
+ order: 3;
774
+ }
775
+
776
+ .tabs-block .slick-arrow.slick-prev {
777
+ left: unset !important;
778
+ }
779
+
780
+ .tabs-block .slick-arrow.slick-next {
781
+ right: unset !important;
782
+ margin-left: 2rem;
783
+ }
784
+ }
785
+
786
+ @media only screen and (min-width: @tabletBreakpoint) and (max-width: @largestTabletScreen) {
787
+ img.slick-image {
788
+ left: -200px;
789
+ width: 550px;
790
+ }
791
+ }
792
+
793
+ @media only screen and (min-width: @computerBreakpoint) and (max-width: @largestSmallMonitor) {
794
+ img.slick-image {
795
+ left: -200px;
796
+ width: 650px;
797
+ }
798
+ }
799
+
800
+ @media only screen and (min-width: @largeMonitorBreakpoint) {
801
+ img.slick-image {
802
+ left: -150px;
803
+ width: 650px;
804
+ }
805
+ }