@openeuropa/bcl-theme-default 0.20.0 → 0.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.
Files changed (41) hide show
  1. package/css/oe-bcl-default.css +344 -0
  2. package/css/oe-bcl-default.css.map +1 -1
  3. package/css/oe-bcl-default.min.css +1 -1
  4. package/css/oe-bcl-default.min.css.map +1 -1
  5. package/icons/bcl-default-icons.svg +1 -1
  6. package/js/oe-bcl-default.bundle.js +242 -76
  7. package/js/oe-bcl-default.bundle.js.map +1 -1
  8. package/js/oe-bcl-default.bundle.min.js +1 -1
  9. package/js/oe-bcl-default.bundle.min.js.map +1 -1
  10. package/js/oe-bcl-default.esm.js +236 -75
  11. package/js/oe-bcl-default.esm.js.map +1 -1
  12. package/js/oe-bcl-default.esm.min.js +1 -1
  13. package/js/oe-bcl-default.esm.min.js.map +1 -1
  14. package/js/oe-bcl-default.umd.js +242 -76
  15. package/js/oe-bcl-default.umd.js.map +1 -1
  16. package/js/oe-bcl-default.umd.min.js +1 -1
  17. package/js/oe-bcl-default.umd.min.js.map +1 -1
  18. package/package.json +5 -5
  19. package/src/icons/icons.js +19 -0
  20. package/src/js/gallery/gallery.js +168 -0
  21. package/src/js/index.esm.js +2 -0
  22. package/src/js/index.umd.js +2 -0
  23. package/src/scss/_bcl-offcanvas.scss +7 -0
  24. package/src/scss/_carousel.scss +85 -0
  25. package/src/scss/_circular-progress-bar.scss +13 -11
  26. package/src/scss/_gallery.scss +262 -0
  27. package/src/scss/_pagination.scss +8 -0
  28. package/src/scss/_search-form.scss +4 -2
  29. package/src/scss/base/_utilities.scss +1 -0
  30. package/src/scss/oe-bcl-default.scss +3 -0
  31. package/templates/bcl-base-templates/listing-page.html.twig +13 -13
  32. package/templates/bcl-card/card.html.twig +35 -22
  33. package/templates/bcl-carousel/carousel.html.twig +26 -5
  34. package/templates/bcl-content-banner/content-banner.html.twig +30 -42
  35. package/templates/bcl-date-block/date-block.html.twig +29 -9
  36. package/templates/bcl-footer/footer.html.twig +3 -1
  37. package/templates/bcl-gallery/gallery.html.twig +203 -0
  38. package/templates/bcl-listing/listing.html.twig +1 -1
  39. package/templates/bcl-pagination/pagination.html.twig +123 -9
  40. package/templates/bcl-person/person.html.twig +44 -0
  41. package/templates/bcl-select/select.html.twig +10 -3
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@openeuropa/bcl-theme-default",
3
3
  "author": "European Commission",
4
4
  "license": "EUPL-1.2",
5
- "version": "0.20.0",
5
+ "version": "0.21.0",
6
6
  "description": "OE - BCL theme default",
7
7
  "scripts": {
8
8
  "align-templates": "lerna --scope \"@openeuropa/bcl-twig-templates\" run prepublish",
@@ -21,9 +21,9 @@
21
21
  "@ecl/resources-ec-logo": "3.2.3",
22
22
  "@ecl/resources-eu-logo": "3.2.3",
23
23
  "@ecl/resources-flag-icons": "3.2.3",
24
- "@openeuropa/bcl-bootstrap": "^0.20.0",
25
- "@openeuropa/bcl-builder": "^0.20.0",
26
- "@openeuropa/bcl-twig-templates": "^0.20.0",
24
+ "@openeuropa/bcl-bootstrap": "^0.21.0",
25
+ "@openeuropa/bcl-builder": "^0.21.0",
26
+ "@openeuropa/bcl-twig-templates": "^0.21.0",
27
27
  "copyfiles": "2.4.1",
28
28
  "cross-env": "7.0.3",
29
29
  "glob": "7.2.0",
@@ -47,5 +47,5 @@
47
47
  "design-system",
48
48
  "twig"
49
49
  ],
50
- "gitHead": "ea13560489a089d0c198f781e75951a9160d2554"
50
+ "gitHead": "18c01b34ca76780f480c692c566dfe507d961ccf"
51
51
  }
@@ -45,6 +45,10 @@ module.exports = [
45
45
  "chevron-down.svg",
46
46
  "chevron-left.svg",
47
47
  "chevron-right.svg",
48
+ "chevron-double-up.svg",
49
+ "chevron-double-down.svg",
50
+ "chevron-double-left.svg",
51
+ "chevron-double-right.svg",
48
52
 
49
53
  //Alerts, warnings and signs
50
54
  "check-lg.svg",
@@ -70,9 +74,11 @@ module.exports = [
70
74
  "plus-circle-fill.svg",
71
75
  "dash-circle.svg",
72
76
  "dash-circle-fill.svg",
77
+ "filter.svg",
73
78
 
74
79
  //Files and folders
75
80
  "file-earmark-pdf.svg",
81
+ "file-arrow-down-fill.svg",
76
82
  "file-pdf-fill.svg",
77
83
  "file-earmark-bar-graph.svg",
78
84
  "file-bar-graph-fill.svg",
@@ -334,4 +340,17 @@ module.exports = [
334
340
  "download.svg",
335
341
  "bookmarks.svg",
336
342
  "bookmarks-fill.svg",
343
+
344
+ // Needed by paragraphs OEL-1348
345
+ "book.svg",
346
+ "check.svg",
347
+ "currency-euro.svg",
348
+ "file.svg",
349
+ "filter.svg",
350
+ "box-arrow-up.svg",
351
+ "image.svg",
352
+ "info.svg",
353
+ "files.svg",
354
+ "share.svg",
355
+ "camera-video.svg",
337
356
  ];
@@ -0,0 +1,168 @@
1
+ /**
2
+ * --------------------------------------------------------------------------
3
+ * Bootstrap (v5.1.3): gallery.js
4
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
+ * --------------------------------------------------------------------------
6
+ */
7
+
8
+ import { defineJQueryPlugin, typeCheckConfig } from '@openeuropa/bcl-bootstrap/js/src/util/index'
9
+ import EventHandler from '@openeuropa/bcl-bootstrap/js/src/dom/event-handler'
10
+ import BaseComponent from '@openeuropa/bcl-bootstrap/js/src/base-component'
11
+ import SelectorEngine from '@openeuropa/bcl-bootstrap/js/src/dom/selector-engine'
12
+ import Manipulator from '@openeuropa/bcl-bootstrap/js/src/dom/manipulator'
13
+
14
+ /**
15
+ * ------------------------------------------------------------------------
16
+ * Constants
17
+ * ------------------------------------------------------------------------
18
+ */
19
+
20
+ const Default = {}
21
+ const DefaultType = {}
22
+
23
+ const NAME = 'gallery'
24
+ const DATA_KEY = 'bs.gallery'
25
+ const EVENT_KEY = `.${DATA_KEY}`
26
+ const DATA_API_KEY = '.data-api'
27
+
28
+ const CAROUSEL_SELECTOR = '.carousel'
29
+ const CAROUSEL_PAGER_SELECTOR = '.carousel-pager span'
30
+ const CAROUSEL_ACTIVE_SELECTOR = '.carousel-item.active'
31
+ const CAROUSEL_ITEM_SELECTOR = '.carousel-item'
32
+ const THUMBNAIL_SELECTOR = '.bcl-gallery__grid a'
33
+ const MODAL_SELECTOR = '.modal'
34
+ const EVENT_MODAL_HIDE = 'hide.bs.modal'
35
+ const CAROUSEL_EVENT = 'slide.bs.carousel'
36
+ const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
37
+
38
+ /**
39
+ * ------------------------------------------------------------------------
40
+ * Class Definition
41
+ * ------------------------------------------------------------------------
42
+ */
43
+
44
+ class Gallery extends BaseComponent {
45
+ constructor(element, config) {
46
+ super(element)
47
+ this._carousel = SelectorEngine.findOne(CAROUSEL_SELECTOR, this._element)
48
+ this._carouselPager = SelectorEngine.findOne(CAROUSEL_PAGER_SELECTOR, this._element)
49
+ this._carouselStartIndex = element.getAttribute('data-gallery-start')
50
+ this._carouselActiveItem = SelectorEngine.find(CAROUSEL_ITEM_SELECTOR, this._carousel)[this._carouselStartIndex]
51
+ this._carouselPager.textContent = Number(this._carouselStartIndex) + 1
52
+ this._modal = SelectorEngine.findOne(MODAL_SELECTOR, this._element)
53
+ this._config = this._getConfig(config)
54
+ this._addEventListeners()
55
+ this._carouselLazyLoad(this._carouselActiveItem)
56
+ }
57
+
58
+ // Getters
59
+ static get NAME() {
60
+ return NAME
61
+ }
62
+
63
+ // Public
64
+ setSlide(event) {
65
+ const slideFrom = SelectorEngine.findOne(CAROUSEL_ACTIVE_SELECTOR, this._carousel)
66
+ const slideTo = event.relatedTarget
67
+ this._carouselLazyLoad(slideTo)
68
+ this._carouselPager.textContent = event.to + 1
69
+ this.stopVideo(slideFrom)
70
+ }
71
+
72
+ stopSlide() {
73
+ const currentSlide = SelectorEngine.findOne(CAROUSEL_ACTIVE_SELECTOR, this._carousel)
74
+ this.stopVideo(currentSlide)
75
+ }
76
+
77
+ stopVideo(slide) {
78
+ const iframe = SelectorEngine.findOne('iframe', slide);
79
+ const video = SelectorEngine.findOne('video', slide);
80
+ if (iframe) {
81
+ iframe.src = iframe.dataset.src;
82
+ } else if (video) {
83
+ video.pause();
84
+ }
85
+ }
86
+
87
+ // Private
88
+ _carouselLazyLoad(slide) {
89
+ const media = SelectorEngine.findOne('[data-src]', slide);
90
+
91
+ if (media && !media.src) {
92
+ media.src = media.dataset.src;
93
+ }
94
+ }
95
+
96
+ _getConfig(config) {
97
+ config = {
98
+ ...Default,
99
+ ...Manipulator.getDataAttributes(this._element),
100
+ ...(typeof config === 'object' ? config : {})
101
+ }
102
+ typeCheckConfig(NAME, config, DefaultType)
103
+ return config
104
+ }
105
+
106
+ _addEventListeners() {
107
+ EventHandler.on(this._carousel, CAROUSEL_EVENT, event => this.setSlide(event))
108
+ EventHandler.on(this._modal, EVENT_MODAL_HIDE, event => this.stopSlide(event))
109
+ }
110
+
111
+ // Static
112
+ static get Default() {
113
+ return Default
114
+ }
115
+
116
+ static galleryInterface(element, config) {
117
+ const data = Gallery.getOrCreateInstance(element, config)
118
+
119
+ let { _config } = data
120
+ if (typeof config === 'object') {
121
+ _config = {
122
+ ..._config,
123
+ ...config
124
+ }
125
+ }
126
+ }
127
+
128
+ static jQueryInterface(config) {
129
+ return this.each(function () {
130
+ const data = Gallery.getOrCreateInstance(this)
131
+
132
+ if (typeof config !== 'string') {
133
+ return
134
+ }
135
+
136
+ if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
137
+ throw new TypeError(`No method named "${config}"`)
138
+ }
139
+
140
+ data[config](this)
141
+ })
142
+ }
143
+ }
144
+
145
+ /**
146
+ * ------------------------------------------------------------------------
147
+ * Data Api implementation
148
+ * ------------------------------------------------------------------------
149
+ */
150
+
151
+ EventHandler.on(document, EVENT_CLICK_DATA_API, THUMBNAIL_SELECTOR, function (event) {
152
+ const gallery = event.srcElement.closest('div.bcl-gallery')
153
+ const firstSlide = event.srcElement.parentNode.getAttribute('data-bs-slide-to');
154
+ gallery.dataset.galleryStart = firstSlide;
155
+
156
+ Gallery.galleryInterface(gallery, Gallery.getInstance(gallery))
157
+ })
158
+
159
+ /**
160
+ * ------------------------------------------------------------------------
161
+ * jQuery
162
+ * ------------------------------------------------------------------------
163
+ * add .gallery to jQuery only if jQuery is present
164
+ */
165
+
166
+ defineJQueryPlugin(Gallery)
167
+
168
+ export default Gallery
@@ -10,6 +10,7 @@ import Button from "@openeuropa/bcl-bootstrap/js/src/button";
10
10
  import Carousel from "@openeuropa/bcl-bootstrap/js/src/carousel";
11
11
  import Collapse from "@openeuropa/bcl-bootstrap/js/src/collapse";
12
12
  import Dropdown from "@openeuropa/bcl-bootstrap/js/src/dropdown";
13
+ import Gallery from "@openeuropa/bcl-theme-default/src/js/gallery/gallery";
13
14
  import Modal from "@openeuropa/bcl-bootstrap/js/src/modal";
14
15
  import Offcanvas from "@openeuropa/bcl-bootstrap/js/src/offcanvas";
15
16
  import Popover from "@openeuropa/bcl-bootstrap/js/src/popover";
@@ -24,6 +25,7 @@ export {
24
25
  Carousel,
25
26
  Collapse,
26
27
  Dropdown,
28
+ Gallery,
27
29
  Modal,
28
30
  Offcanvas,
29
31
  Popover,
@@ -10,6 +10,7 @@ import Button from "@openeuropa/bcl-bootstrap/js/src/button";
10
10
  import Carousel from "@openeuropa/bcl-bootstrap/js/src/carousel";
11
11
  import Collapse from "@openeuropa/bcl-bootstrap/js/src/collapse";
12
12
  import Dropdown from "@openeuropa/bcl-bootstrap/js/src/dropdown";
13
+ import Gallery from "@openeuropa/bcl-theme-default/src/js/gallery/gallery";
13
14
  import Modal from "@openeuropa/bcl-bootstrap/js/src/modal";
14
15
  import Offcanvas from "@openeuropa/bcl-bootstrap/js/src/offcanvas";
15
16
  import Popover from "@openeuropa/bcl-bootstrap/js/src/popover";
@@ -24,6 +25,7 @@ export default {
24
25
  Carousel,
25
26
  Collapse,
26
27
  Dropdown,
28
+ Gallery,
27
29
  Modal,
28
30
  Offcanvas,
29
31
  Popover,
@@ -5,10 +5,17 @@
5
5
  visibility: visible !important; // stylelint-disable-line declaration-no-important
6
6
  border: none;
7
7
  transform: none;
8
+ box-shadow: none;
8
9
 
9
10
  .offcanvas-body {
10
11
  overflow: visible;
11
12
  }
13
+
14
+ .offcanvas-title {
15
+ height: 38px;
16
+ display: flex;
17
+ align-items: center;
18
+ }
12
19
  }
13
20
 
14
21
  .bcl-offcanvas + .offcanvas-backdrop {
@@ -0,0 +1,85 @@
1
+ $indicator-size: 8px;
2
+
3
+ .carousel-indicators {
4
+ background-color: rgba(0, 0, 0, 0.5);
5
+ margin: 0;
6
+ [data-bs-target] {
7
+ width: $indicator-size;
8
+ height: $indicator-size;
9
+ margin: map-get($spacers, "1-5") map-get($spacers, 2) map-get($spacers, 3);
10
+ border-radius: 50%;
11
+ }
12
+ }
13
+
14
+ .carousel-caption {
15
+ width: 100%;
16
+ left: 0;
17
+ right: 0;
18
+ background-color: rgba(0, 0, 0, 0.5);
19
+ bottom: 0;
20
+ padding: map-get($spacers, 3) 0 map-get($spacers, 4);
21
+ p {
22
+ margin-bottom: 0;
23
+ }
24
+ a {
25
+ color: $white;
26
+ text-decoration-color: $white;
27
+ }
28
+ }
29
+
30
+ .carousel-dark {
31
+ .carousel-caption {
32
+ background-color: rgba(255, 255, 255, 0.5);
33
+ a {
34
+ color: $black;
35
+ text-decoration-color: $black;
36
+ }
37
+ }
38
+
39
+ .carousel-indicators {
40
+ background-color: rgba(255, 255, 255, 0.5);
41
+ }
42
+ }
43
+
44
+ .carousel-control-next,
45
+ .carousel-control-prev {
46
+ opacity: 1;
47
+ &:hover {
48
+ opacity: 1;
49
+ }
50
+ }
51
+
52
+ .carousel-control-prev-icon,
53
+ .carousel-control-next-icon {
54
+ width: 40px;
55
+ height: 40px;
56
+ background-size: 60% 60%;
57
+ background-color: rgba(0, 0, 0, 0.5);
58
+ border-radius: 4px;
59
+ }
60
+
61
+ .carousel-control-next-icon {
62
+ background-position: 9px center;
63
+ }
64
+
65
+ .carousel-control-prev-icon {
66
+ background-position: 7px center;
67
+ }
68
+
69
+ .carousel.rounded-indicators {
70
+ .carousel-control-prev-icon,
71
+ .carousel-control-next-icon {
72
+ border-radius: 50%;
73
+ }
74
+ }
75
+
76
+ @include media-breakpoint-up(md) {
77
+ .carousel-indicators {
78
+ & + .carousel-inner {
79
+ .carousel-caption {
80
+ bottom: 50px;
81
+ padding-bottom: 0;
82
+ }
83
+ }
84
+ }
85
+ }
@@ -1,3 +1,5 @@
1
+ @use "sass:math";
2
+
1
3
  //styling
2
4
  $borderWidth: 12px;
3
5
  $animationTime: 1s;
@@ -48,8 +50,8 @@ $howManySteps: 20;
48
50
  left: 0;
49
51
  .circular-progress-bar {
50
52
  left: 100%;
51
- border-top-right-radius: ($size / 2);
52
- border-bottom-right-radius: ($size / 2);
53
+ border-top-right-radius: math.div($size, 2);
54
+ border-bottom-right-radius: math.div($size, 2);
53
55
  border-left: 0;
54
56
  transform-origin: center left;
55
57
  }
@@ -59,8 +61,8 @@ $howManySteps: 20;
59
61
  right: 0;
60
62
  .circular-progress-bar {
61
63
  left: -100%;
62
- border-top-left-radius: ($size / 2);
63
- border-bottom-left-radius: ($size / 2);
64
+ border-top-left-radius: math.div($size, 2);
65
+ border-bottom-left-radius: math.div($size, 2);
64
66
  border-right: 0;
65
67
  transform-origin: center right;
66
68
  }
@@ -70,10 +72,10 @@ $howManySteps: 20;
70
72
  Due to the split circle of progress-left and progress right, we must use the animations on each side.
71
73
  */
72
74
  @for $i from 1 through $howManySteps {
73
- $stepName: ($i * (100 / $howManySteps));
75
+ $stepName: ($i * math.div(100, $howManySteps));
74
76
 
75
77
  //animation only the left side if below 50%
76
- @if $i <= ($howManySteps / 2) {
78
+ @if $i <= math.div($howManySteps, 2) {
77
79
  .circular-progress[data-percentage="#{$stepName}"] {
78
80
  .circular-progress-right .circular-progress-bar {
79
81
  animation: loading-#{$i} $animationTime linear forwards;
@@ -84,18 +86,18 @@ Due to the split circle of progress-left and progress right, we must use the ani
84
86
  }
85
87
  }
86
88
  //animation only the right side if above 50%
87
- @if $i > ($howManySteps / 2) {
89
+ @if $i > math.div($howManySteps, 2) {
88
90
  .circular-progress[data-percentage="#{$stepName}"] {
89
91
  .circular-progress-right .circular-progress-bar {
90
92
  // prettier-ignore
91
- animation: loading-#{($howManySteps / 2)}
93
+ animation: loading-#{ math.div($howManySteps, 2)}
92
94
  $animationTime
93
95
  linear
94
96
  forwards; //set the animation to longest animation
95
97
  }
96
98
  .circular-progress-left .circular-progress-bar {
97
99
  // prettier-ignore
98
- animation: loading-#{$i - ($howManySteps / 2)}
100
+ animation: loading-#{$i - math.div($howManySteps, 2)}
99
101
  $animationTime
100
102
  linear
101
103
  forwards
@@ -106,8 +108,8 @@ Due to the split circle of progress-left and progress right, we must use the ani
106
108
  }
107
109
 
108
110
  //animation
109
- @for $i from 1 through ($howManySteps / 2) {
110
- $degrees: (180 / ($howManySteps / 2));
111
+ @for $i from 1 through math.div($howManySteps, 2) {
112
+ $degrees: math.div(180, math.div($howManySteps, 2));
111
113
  $degrees: ($degrees * $i);
112
114
  @keyframes loading-#{$i} {
113
115
  0% {
@@ -0,0 +1,262 @@
1
+ .bcl-gallery {
2
+ .bcl-gallery__thumbnails {
3
+ border-radius: $border-radius;
4
+ overflow: hidden;
5
+ }
6
+
7
+ ul.bcl-gallery__grid {
8
+ list-style: none;
9
+ padding: 0;
10
+ margin-bottom: 0;
11
+ }
12
+
13
+ .bcl-gallery__item {
14
+ position: relative;
15
+ }
16
+
17
+ .bcl-gallery__item-overlay {
18
+ display: flex;
19
+ flex-direction: column;
20
+ justify-content: center;
21
+ align-items: center;
22
+ position: absolute;
23
+ top: 0;
24
+ left: 0;
25
+ width: 100%;
26
+ height: 100%;
27
+ padding: 0 map-get($spacers, 3);
28
+ transition: background-color 0.2s ease;
29
+ }
30
+
31
+ .bcl-gallery__item-play-icon {
32
+ background-color: rgba(0, 0, 0, 0.5);
33
+ display: flex;
34
+ justify-content: center;
35
+ align-items: center;
36
+ width: 32px;
37
+ height: 32px;
38
+ border-radius: $border-radius;
39
+ pointer-events: none;
40
+
41
+ .bi {
42
+ fill: $white;
43
+ }
44
+ }
45
+
46
+ .bcl-gallery__item-caption {
47
+ display: none;
48
+ color: $white;
49
+ text-align: center;
50
+ pointer-events: none;
51
+
52
+ h5 {
53
+ margin-bottom: 0;
54
+ }
55
+ }
56
+
57
+ .bcl-gallery__item-description {
58
+ display: none;
59
+ margin-top: map-get($spacers, 1);
60
+ }
61
+
62
+ ul.bcl-gallery__grid li:not(:last-child) {
63
+ margin-bottom: map-get($spacers, 2);
64
+ }
65
+
66
+ .bcl-gallery__thumbnails-collaspe {
67
+ ul.bcl-gallery__grid {
68
+ margin-top: map-get($spacers, 2);
69
+ }
70
+ }
71
+
72
+ .bcl-gallery__collapse {
73
+ &[aria-expanded="false"] {
74
+ .label-expanded {
75
+ display: none;
76
+ }
77
+ }
78
+ &[aria-expanded="true"] {
79
+ .label-collapsed {
80
+ display: none;
81
+ }
82
+ svg {
83
+ transform: rotate(180deg);
84
+ }
85
+ }
86
+ }
87
+
88
+ .carousel {
89
+ height: 100%;
90
+ width: 100%;
91
+ max-height: 500px;
92
+ }
93
+
94
+ .carousel-inner {
95
+ height: 100%;
96
+ }
97
+
98
+ .carousel-item {
99
+ position: relative;
100
+ height: 100%;
101
+ text-align: center;
102
+ z-index: 1;
103
+ }
104
+
105
+ .modal-content {
106
+ background: black;
107
+ justify-content: center;
108
+ }
109
+
110
+ .modal-title {
111
+ width: 35%;
112
+ color: white;
113
+ }
114
+
115
+ .carousel-pager {
116
+ display: flex;
117
+ justify-content: center;
118
+ color: white;
119
+ width: 30%;
120
+
121
+ span {
122
+ display: inline-block;
123
+ margin-right: 5px;
124
+ }
125
+ }
126
+
127
+ .modal-close {
128
+ display: flex;
129
+ justify-content: end;
130
+ width: 35%;
131
+
132
+ .btn-close {
133
+ filter: invert(100%);
134
+ opacity: 1;
135
+ }
136
+ }
137
+
138
+ .carousel-control-next,
139
+ .carousel-control-prev {
140
+ // avoid overlapping medias and make play button of the video accessible
141
+ top: 50%;
142
+ height: 20%;
143
+ transform: translateY(-50%);
144
+ }
145
+
146
+ iframe,
147
+ video {
148
+ width: 100%;
149
+ height: 100%;
150
+ aspect-ratio: 16 / 9;
151
+ max-width: 900px;
152
+ object-fit: contain;
153
+ }
154
+
155
+ img {
156
+ display: inline-block;
157
+ height: 100%;
158
+ width: 100%;
159
+ object-fit: contain;
160
+ }
161
+
162
+ /* lazyload */
163
+ img:not([src]):not([srcset]) {
164
+ visibility: hidden;
165
+ }
166
+
167
+ @keyframes lazy_spinner {
168
+ to {
169
+ transform: rotate(360deg);
170
+ }
171
+ }
172
+
173
+ .carousel-item:after {
174
+ content: "";
175
+ box-sizing: border-box;
176
+ position: absolute;
177
+ top: 50%;
178
+ left: 50%;
179
+ width: 20px;
180
+ height: 20px;
181
+ margin-top: -10px;
182
+ margin-left: -10px;
183
+ border-radius: 50%;
184
+ border: 2px solid #ccc;
185
+ border-top-color: #000;
186
+ animation: lazy_spinner 0.6s linear infinite;
187
+ z-index: -1;
188
+ }
189
+
190
+ @include media-breakpoint-up(sm) {
191
+ ul.bcl-gallery__grid {
192
+ display: grid;
193
+ grid-template-rows: 1fr 1fr 0;
194
+ grid-gap: map-get($spacers, 2);
195
+ grid-template-columns: repeat(4, 1fr);
196
+ margin-bottom: -#{map-get($spacers, 2)};
197
+ }
198
+
199
+ ul.bcl-gallery__grid li:not(:last-child) {
200
+ margin-bottom: 0;
201
+ }
202
+
203
+ ul.bcl-gallery__grid li:first-child {
204
+ grid-column: 1 / 3;
205
+ grid-row: 1 / 3;
206
+ }
207
+
208
+ .bcl-gallery__thumbnails-collaspe {
209
+ ul.bcl-gallery__grid {
210
+ margin-top: map-get($spacers, 2);
211
+ }
212
+ ul.bcl-gallery__grid:nth-child(odd) li:first-child {
213
+ grid-column: auto;
214
+ grid-row: auto;
215
+ }
216
+ ul.bcl-gallery__grid:nth-child(odd) li:last-child {
217
+ grid-column: 3 / 5;
218
+ grid-row: 1 / 3;
219
+ }
220
+ }
221
+
222
+ .bcl-gallery__item:hover {
223
+ .bcl-gallery__item-overlay {
224
+ background-color: rgba(0, 0, 0, 0.5);
225
+ }
226
+ .bcl-gallery__item-play-icon {
227
+ background-color: $white;
228
+
229
+ .bi {
230
+ fill: $black;
231
+ }
232
+ }
233
+ }
234
+
235
+ .modal-title,
236
+ .modal-close {
237
+ width: 45%;
238
+ }
239
+
240
+ .carousel-pager {
241
+ width: 10%;
242
+ }
243
+ }
244
+
245
+ @include media-breakpoint-up(md) {
246
+ .bcl-gallery__item:hover {
247
+ .bcl-gallery__item-caption {
248
+ display: block;
249
+ }
250
+
251
+ .bcl-gallery__item-play-icon + .bcl-gallery__item-caption {
252
+ margin-top: map-get($spacers, 2);
253
+ }
254
+ }
255
+ }
256
+
257
+ @include media-breakpoint-up(lg) {
258
+ .bcl-gallery__item-description {
259
+ display: block;
260
+ }
261
+ }
262
+ }