@kitconcept/volto-light-theme 7.0.0-alpha.19 → 7.0.0-alpha.20

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.draft CHANGED
@@ -1,13 +1,11 @@
1
- ## 7.0.0-alpha.19 (2025-07-25)
1
+ ## 7.0.0-alpha.20 (2025-07-29)
2
2
 
3
- ### Bugfix
3
+ ### Feature
4
4
 
5
- - Fix the listing body width in grid listing variation. @iFlameing [#618](https://github.com/kitconcept/volto-light-theme/pull/618)
5
+ - Added Slider Variations @Tishasoumya-02
6
6
 
7
- ### Internal
7
+ ### Bugfix
8
8
 
9
- - Add cypress test for sort_on, sort_order for eventCalendar block. @iFlameing [#619](https://github.com/kitconcept/volto-light-theme/pull/619)
10
- - Fix alt tag fallback to title if srcAlt is missing in IconLinkList @iRohitSingh [#620](https://github.com/kitconcept/volto-light-theme/pull/620)
11
- - Use volto-dsgvo-banner 2.5.1 @sneridagh
9
+ - Fix alt tag fallback in IconLinkList @iRohitSingh [#621](https://github.com/kitconcept/volto-light-theme/pull/621)
12
10
 
13
11
 
package/CHANGELOG.md CHANGED
@@ -8,6 +8,16 @@
8
8
 
9
9
  <!-- towncrier release notes start -->
10
10
 
11
+ ## 7.0.0-alpha.20 (2025-07-29)
12
+
13
+ ### Feature
14
+
15
+ - Added Slider Variations @Tishasoumya-02
16
+
17
+ ### Bugfix
18
+
19
+ - Fix alt tag fallback in IconLinkList @iRohitSingh [#621](https://github.com/kitconcept/volto-light-theme/pull/621)
20
+
11
21
  ## 7.0.0-alpha.19 (2025-07-25)
12
22
 
13
23
  ### Bugfix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitconcept/volto-light-theme",
3
- "version": "7.0.0-alpha.19",
3
+ "version": "7.0.0-alpha.20",
4
4
  "description": "Volto Light Theme by kitconcept",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -42,7 +42,7 @@
42
42
  "typescript": "^5.7.3",
43
43
  "release-it": "^19.0.3",
44
44
  "vitest": "^3.1.2",
45
- "@plone/types": "1.4.5"
45
+ "@plone/types": "1.4.1"
46
46
  },
47
47
  "dependencies": {
48
48
  "@dnd-kit/core": "6.0.8",
@@ -52,6 +52,8 @@
52
52
  "react-aria-components": "^1.7.0",
53
53
  "react-colorful": "^5.6.1",
54
54
  "uuid": "^11.0.0",
55
+ "embla-carousel-autoplay": "^8.0.0",
56
+ "embla-carousel-react": "^8.0.0",
55
57
  "@plone/components": "^3.0.2"
56
58
  },
57
59
  "peerDependencies": {
@@ -100,6 +100,7 @@ const SliderBody = ({
100
100
  <MaybeWrap
101
101
  condition={!isEditMode}
102
102
  as={UniversalLink}
103
+ className="link-container"
103
104
  href={href['@id']}
104
105
  target={
105
106
  data.openLinkInNewTab ||
@@ -0,0 +1,152 @@
1
+ import React from 'react';
2
+ import { useIntl, defineMessages } from 'react-intl';
3
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
4
+ import MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
5
+ import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
6
+ import { Input, Button, Message } from 'semantic-ui-react';
7
+ import { isInternalURL } from '@plone/volto/helpers/Url/Url';
8
+ import cx from 'classnames';
9
+ import navTreeSVG from '@plone/volto/icons/nav.svg';
10
+ import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
11
+ import config from '@plone/volto/registry';
12
+
13
+ const messages = defineMessages({
14
+ PleaseChooseContent: {
15
+ id: 'Please choose an existing content as source for this element',
16
+ defaultMessage:
17
+ 'Please choose an existing content as source for this element',
18
+ },
19
+ moreInfo: {
20
+ id: 'moreInfo',
21
+ defaultMessage: 'More info',
22
+ },
23
+ source: {
24
+ id: 'Source',
25
+ defaultMessage: 'Source',
26
+ },
27
+ ButtonText: {
28
+ id: 'Continue reading',
29
+ defaultMessage: 'Continue reading',
30
+ },
31
+ });
32
+
33
+ const DefaultImage = (props) => <img {...props} alt={props.alt || ''} />;
34
+
35
+ const SliderVariants = ({
36
+ index,
37
+ onChangeBlock,
38
+ block,
39
+ data,
40
+ dataBlock,
41
+ isEditMode,
42
+ openObjectBrowser,
43
+ }) => {
44
+ const intl = useIntl();
45
+ const href = data.href?.[0];
46
+ const image = data.preview_image?.[0];
47
+
48
+ const Image = config.getComponent('Image').component || DefaultImage;
49
+ const { openExternalLinkInNewTab } = config.settings;
50
+
51
+ const handleClick = () => {
52
+ openObjectBrowser({
53
+ onSelectItem: (url, document) => {
54
+ dataBlock.slides[index].title = document.Title;
55
+ dataBlock.slides[index].description = document.Description;
56
+ dataBlock.slides[index].href = [
57
+ {
58
+ '@id': document['@id'],
59
+ Title: document.Title,
60
+ Description: document.Description,
61
+ title: document.Title,
62
+ image_field: document.image_field,
63
+ hasPreviewImage: document.hasPreviewImage,
64
+ },
65
+ ];
66
+ onChangeBlock(block, dataBlock);
67
+ },
68
+ mode: 'link',
69
+ });
70
+ };
71
+
72
+ return (
73
+ <div
74
+ className={cx('grid-teaser-item top', {
75
+ 'empty-slide': !href && isEditMode,
76
+ })}
77
+ >
78
+ {!href && isEditMode && (
79
+ <Message>
80
+ <div className="grid-teaser-item default">
81
+ <img src={imageBlockSVG} alt="" />
82
+ <p>{intl.formatMessage(messages.PleaseChooseContent)}</p>
83
+ <div className="toolbar-inner">
84
+ <Button.Group>
85
+ <Button onClick={handleClick} icon basic>
86
+ <Icon name={navTreeSVG} size="24px" />
87
+ </Button>
88
+ </Button.Group>
89
+ <Input
90
+ placeholder={`${intl.formatMessage(messages.source)}...`}
91
+ onClick={handleClick}
92
+ onFocus={(e) => e.target.blur()}
93
+ />
94
+ </div>
95
+ </div>
96
+ </Message>
97
+ )}
98
+ {href && (
99
+ <MaybeWrap
100
+ condition={!isEditMode}
101
+ as={UniversalLink}
102
+ href={href['@id']}
103
+ className="link-container"
104
+ target={
105
+ data.openLinkInNewTab ||
106
+ (openExternalLinkInNewTab && !isInternalURL(href['@id']))
107
+ ? '_blank'
108
+ : null
109
+ }
110
+ tabIndex="-1"
111
+ >
112
+ <div
113
+ className={cx(
114
+ 'teaser-item top',
115
+ `has--slider--flagAlign--${data.flagAlign}`,
116
+ dataBlock.variation,
117
+ )}
118
+ >
119
+ {(href?.hasPreviewImage || href.image_field || image) && (
120
+ <div className="highlight-image-wrapper gradient">
121
+ <Image
122
+ item={image || href}
123
+ imageField={image ? image.image_field : href.image_field}
124
+ alt=""
125
+ loading="lazy"
126
+ responsive={true}
127
+ />
128
+ </div>
129
+ )}
130
+ <div className="teaser-item-title fix-width-issue">
131
+ <div className="title">
132
+ {data?.head_title && (
133
+ <span className="supertitle">{data?.head_title}</span>
134
+ )}
135
+ <h2>{data?.nav_title || data?.title}</h2>
136
+ </div>
137
+ <p>{data?.description}</p>
138
+
139
+ {!data.hideButton && (
140
+ <Button tabIndex={'-1'}>
141
+ {data.buttonText || intl.formatMessage(messages.ButtonText)}
142
+ </Button>
143
+ )}
144
+ </div>
145
+ </div>
146
+ </MaybeWrap>
147
+ )}
148
+ </div>
149
+ );
150
+ };
151
+
152
+ export default SliderVariants;
@@ -0,0 +1,179 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { Message } from 'semantic-ui-react';
3
+ import useEmblaCarousel from 'embla-carousel-react';
4
+ import Autoplay from 'embla-carousel-autoplay';
5
+ import cx from 'classnames';
6
+ import { defineMessages, useIntl } from 'react-intl';
7
+ import Body from '@kitconcept/volto-slider-block/components/Body';
8
+ import withBlockExtensions from '@plone/volto/helpers/Extensions/withBlockExtensions';
9
+ import {
10
+ DotButton,
11
+ NextButton,
12
+ PrevButton,
13
+ } from '@kitconcept/volto-slider-block/components/DotsAndArrows';
14
+ import teaserTemplate from '@kitconcept/volto-slider-block/icons/teaser-template.svg';
15
+
16
+ const messages = defineMessages({
17
+ PleaseChooseContent: {
18
+ id: 'Please choose an existing content as source for this element',
19
+ defaultMessage:
20
+ 'Please choose an existing content as source for this element',
21
+ },
22
+ });
23
+
24
+ const SliderView = (props) => {
25
+ const {
26
+ className,
27
+ data,
28
+ isEditMode = false,
29
+ block,
30
+ openObjectBrowser,
31
+ onChangeBlock,
32
+ slideIndex,
33
+ setSlideIndex,
34
+ } = props;
35
+ const intl = useIntl();
36
+
37
+ const [prevBtnDisabled, setPrevBtnDisabled] = useState(true);
38
+ const [nextBtnDisabled, setNextBtnDisabled] = useState(true);
39
+ const [selectedIndex, setSelectedIndex] = useState(0);
40
+ const [scrollSnaps, setScrollSnaps] = useState([]);
41
+ const autoplay =
42
+ data.autoplayEnabled !== undefined ? data.autoplayEnabled : false;
43
+ const autoplayOptions = {
44
+ delay: data.autoplayDelay,
45
+ jump: data.autoplayJump,
46
+ };
47
+ const plugins = isEditMode ? [] : autoplay ? [Autoplay(autoplayOptions)] : [];
48
+
49
+ const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, plugins);
50
+
51
+ const scrollPrev = useCallback(() => {
52
+ if (emblaApi) {
53
+ emblaApi.scrollPrev();
54
+ setSlideIndex && setSlideIndex(selectedIndex - 1);
55
+ }
56
+ }, [emblaApi, selectedIndex, setSlideIndex]);
57
+
58
+ const scrollNext = useCallback(() => {
59
+ if (emblaApi) {
60
+ emblaApi.scrollNext();
61
+ setSlideIndex && setSlideIndex(selectedIndex + 1);
62
+ }
63
+ }, [emblaApi, selectedIndex, setSlideIndex]);
64
+
65
+ const scrollTo = useCallback(
66
+ (index) => {
67
+ if (emblaApi) {
68
+ emblaApi.scrollTo(index);
69
+ setSlideIndex && setSlideIndex(index);
70
+ }
71
+ },
72
+ [emblaApi, setSlideIndex],
73
+ );
74
+
75
+ const onInit = useCallback((emblaApi) => {
76
+ setScrollSnaps(emblaApi.scrollSnapList());
77
+ }, []);
78
+
79
+ const onSelect = useCallback((emblaApi) => {
80
+ setSelectedIndex(emblaApi.selectedScrollSnap());
81
+ setPrevBtnDisabled(!emblaApi.canScrollPrev());
82
+ setNextBtnDisabled(!emblaApi.canScrollNext());
83
+ }, []);
84
+
85
+ useEffect(() => {
86
+ if (!emblaApi) return;
87
+
88
+ onInit(emblaApi);
89
+ onSelect(emblaApi);
90
+ emblaApi.on('reInit', onInit);
91
+ emblaApi.on('reInit', onSelect);
92
+ emblaApi.on('select', onSelect);
93
+ }, [emblaApi, onInit, onSelect]);
94
+
95
+ useEffect(() => {
96
+ // This syncs the current slide with the objectwidget (or other sources
97
+ // able to access the slider context)
98
+ // that can modify the SliderContext (and come here via props slideIndex)
99
+ if (isEditMode) {
100
+ scrollTo(slideIndex);
101
+ }
102
+ }, [slideIndex, scrollTo, isEditMode]);
103
+
104
+ const sliderContainerWidth = emblaApi
105
+ ?.rootNode()
106
+ .getBoundingClientRect().width;
107
+
108
+ return (
109
+ <>
110
+ {/* START CUSTOMIZATION */}
111
+ <div
112
+ className={cx('block slider', data.variation || 'default', className)}
113
+ style={{ '--slider-container-width': `${sliderContainerWidth}px` }}
114
+ >
115
+ {/* END CUSTOMIZATION */}
116
+ {(data.slides?.length === 0 || !data.slides) && isEditMode && (
117
+ <Message>
118
+ <div className="teaser-item default">
119
+ <img src={teaserTemplate} alt="" />
120
+ <p>{intl.formatMessage(messages.PleaseChooseContent)}</p>
121
+ </div>
122
+ </Message>
123
+ )}
124
+ {data.slides?.length > 0 && (
125
+ <>
126
+ <div className="slider-wrapper">
127
+ {!data.hideArrows && data.slides?.length > 1 && (
128
+ <>
129
+ <PrevButton onClick={scrollPrev} disabled={prevBtnDisabled} />
130
+ <NextButton onClick={scrollNext} disabled={nextBtnDisabled} />
131
+ </>
132
+ )}
133
+
134
+ <div className="slider-viewport" ref={emblaRef}>
135
+ <div className="slider-container">
136
+ {data.slides &&
137
+ data.slides.map((item, index) => {
138
+ return (
139
+ <div key={item['@id']} className="slider-slide">
140
+ <Body
141
+ {...props}
142
+ key={item['@id']}
143
+ data={item}
144
+ isEditMode={isEditMode}
145
+ dataBlock={data}
146
+ index={index}
147
+ block={block}
148
+ openObjectBrowser={openObjectBrowser}
149
+ onChangeBlock={onChangeBlock}
150
+ isActive={selectedIndex === index}
151
+ />
152
+ </div>
153
+ );
154
+ })}
155
+ </div>
156
+ </div>
157
+ </div>
158
+ {data.slides?.length > 1 && (
159
+ <div className="slider-dots">
160
+ {scrollSnaps.map((_, index) => (
161
+ <DotButton
162
+ key={index}
163
+ index={index}
164
+ onClick={() => scrollTo(index)}
165
+ className={'slider-dot'.concat(
166
+ index === selectedIndex ? ' slider-dot--selected' : '',
167
+ )}
168
+ />
169
+ ))}
170
+ </div>
171
+ )}
172
+ </>
173
+ )}
174
+ </div>
175
+ </>
176
+ );
177
+ };
178
+
179
+ export default withBlockExtensions(SliderView);
@@ -21,6 +21,8 @@ const StickyMenu = ({ content }: { content: Content }) => {
21
21
  return (
22
22
  <div
23
23
  className="sticky-menu"
24
+ role="navigation"
25
+ aria-label="Sticky menu"
24
26
  style={
25
27
  {
26
28
  '--sticky-menu-color': sticky_menu_color,
@@ -45,6 +45,8 @@ import SearchBlockViewEvent from '../components/Blocks/EventCalendar/Search/Sear
45
45
  import SearchBlockEditEvent from '../components/Blocks/EventCalendar/Search/SearchBlockEdit';
46
46
  import SearchBlockSchemaEvent from '../components/Blocks/EventCalendar/Search/schema';
47
47
  import EventCalenderTemplate from '../components/Blocks/EventCalendar/Search/components/EventTemplate';
48
+ import SliderVariants from '../components/Blocks/Slider/SliderVariants';
49
+ import DefaultBody from '../customizations/@kitconcept/volto-slider-block/components/DefaultBody';
48
50
 
49
51
  declare module '@plone/types' {
50
52
  export interface BlocksConfigData {
@@ -414,6 +416,40 @@ export default function install(config: ConfigType) {
414
416
  // Slider Block
415
417
  config.blocks.blocksConfig.slider = {
416
418
  ...config.blocks.blocksConfig.slider,
419
+ variations: [
420
+ {
421
+ id: 'default',
422
+ title: 'Default',
423
+ isDefault: true,
424
+ view: DefaultBody,
425
+ },
426
+ {
427
+ id: 'full-height',
428
+ title: 'Full Height',
429
+ view: SliderVariants,
430
+ },
431
+ {
432
+ id: 'side',
433
+ title: 'Side',
434
+ view: SliderVariants,
435
+ },
436
+ /* Why do we have two full-side variations?
437
+ because in listings we don't want to show the eventCalender variation and we dont
438
+ have any way to remove it from the list of variations in listing blocks because
439
+ in eventCaledarblock we use listingbody component for showing the variation.
440
+ you can see the css in listing.scss where we are hiding the option 3 using css
441
+ line no.6 */
442
+ {
443
+ id: 'full-side',
444
+ title: 'Full Side',
445
+ view: SliderVariants,
446
+ },
447
+ {
448
+ id: 'full-side',
449
+ title: 'Full Side',
450
+ view: SliderVariants,
451
+ },
452
+ ],
417
453
  schemaEnhancer: sliderBlockSchemaEnhancer,
418
454
  };
419
455
 
@@ -0,0 +1,11 @@
1
+ /**
2
+ * OVERRIDE View.jsx
3
+ * REASON: Adding variants.
4
+ * VERSION: 6.3.1
5
+ * DATE: 2025-07-18
6
+ * DEVELOPER: @Tishasoumya-02
7
+ */
8
+
9
+ import View from '../../../../components/Blocks/Slider/View';
10
+
11
+ export default View;
@@ -59,10 +59,7 @@ const IconLinkList = (props: IconLinkListProps) => {
59
59
  openLinkInNewTab={item.openInNewTab}
60
60
  >
61
61
  <div className="image-wrapper">
62
- <img
63
- src={itemInfo.src}
64
- alt={itemInfo.srcAlt || itemInfo.title}
65
- />
62
+ <img src={itemInfo.src} alt={itemInfo.srcAlt || ''} />
66
63
  </div>
67
64
  <span>{itemInfo.title}</span>
68
65
  </ConditionalLink>
@@ -8,32 +8,41 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
8
8
  }
9
9
 
10
10
  .slider-viewport {
11
- margin-bottom: 0;
11
+ margin-bottom: $spacing-medium;
12
12
  }
13
13
 
14
14
  .slider-dots {
15
- padding-bottom: 40px;
16
- }
17
-
18
- .highlight-image-wrapper {
19
- display: flex; // Small gap was appearing between the wrapper and the image (??)
20
-
21
- img {
22
- // Override Volto's Image Component inline style aspect ratio.
23
- aspect-ratio: var(
24
- --image-aspect-ratio,
25
- $sliderImagesAspectRatio
26
- ) !important;
27
- }
15
+ padding-bottom: $spacing-medium;
28
16
  }
29
17
 
30
18
  .teaser-item,
31
19
  .grid-teaser-item {
32
20
  flex-direction: column;
21
+ @media only screen and (max-width: $computer-width) {
22
+ height: 100%;
23
+ }
33
24
  }
25
+ .link-container {
26
+ @media only screen and (max-width: $computer-width) {
27
+ height: 100%;
28
+ }
29
+ }
30
+
34
31
  .teaser-item {
35
- padding-bottom: $spacing-medium;
32
+ .highlight-image-wrapper {
33
+ display: flex; // Small gap was appearing between the wrapper and the image (??)
36
34
 
35
+ img {
36
+ // Override Volto's Image Component inline style aspect ratio.
37
+ aspect-ratio: var(
38
+ --image-aspect-ratio,
39
+ $sliderImagesAspectRatio
40
+ ) !important;
41
+ }
42
+ }
43
+ @media only screen and (max-width: $computer-width) {
44
+ display: flex;
45
+ }
37
46
  .teaser-item-title {
38
47
  position: absolute;
39
48
  top: 50%;
@@ -51,6 +60,7 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
51
60
  @media only screen and (max-width: $computer-width) {
52
61
  position: static;
53
62
  width: 100%;
63
+ height: 100%;
54
64
  padding: 60px 20px;
55
65
  background: $black;
56
66
  transform: none;
@@ -112,4 +122,243 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
112
122
  line-height: 20px;
113
123
  text-align: center;
114
124
  }
125
+
126
+ &.side {
127
+ .teaser-item {
128
+ display: grid;
129
+ align-items: center;
130
+ padding: 0 130px;
131
+ aspect-ratio: 16/9;
132
+ background: rgba(0, 0, 0, 0.75);
133
+ gap: 70px;
134
+ grid-template-areas: 'images content';
135
+ grid-template-columns: 1fr 1fr;
136
+ grid-template-rows: auto;
137
+ @media only screen and (max-width: $computer-width) {
138
+ display: flex;
139
+ padding: 0 0;
140
+ aspect-ratio: auto;
141
+ gap: 0;
142
+ }
143
+
144
+ &.has--slider--flagAlign--right {
145
+ grid-template-areas: 'images content';
146
+ }
147
+ &.has--slider--flagAlign--left {
148
+ grid-template-areas: 'content images';
149
+ }
150
+
151
+ .highlight-image-wrapper {
152
+ grid-area: images;
153
+
154
+ img {
155
+ aspect-ratio: var(
156
+ --image-aspect-ratio,
157
+ $sliderImagesAspectRatio
158
+ ) !important;
159
+
160
+ @media only screen and (max-width: $computer-width) {
161
+ width: 100%;
162
+ }
163
+ }
164
+ }
165
+ .teaser-item-title {
166
+ position: relative;
167
+ top: 0;
168
+ width: 100%;
169
+ align-content: center;
170
+ padding: 0;
171
+ background: none;
172
+ color: white;
173
+ grid-area: content;
174
+ transform: none;
175
+
176
+ @media only screen and (max-width: $computer-width) {
177
+ position: relative;
178
+ width: 100%;
179
+ height: 100%;
180
+ padding: 60px 20px;
181
+ background: $black;
182
+ transform: none;
183
+ }
184
+ }
185
+ }
186
+ .slider-button {
187
+ width: 130px;
188
+ background: rgba(0, 0, 0, 0);
189
+
190
+ svg.icon {
191
+ width: 50px !important;
192
+ height: 50px !important;
193
+ padding: 40px;
194
+ background: rgba(0, 0, 0, 0.15);
195
+ }
196
+ }
197
+ }
198
+ &.full-side {
199
+ .teaser-item {
200
+ display: grid;
201
+ align-items: center;
202
+ aspect-ratio: 16/9;
203
+ background: rgba(0, 0, 0, 0.75);
204
+ gap: 60px;
205
+ grid-template-areas: 'images content';
206
+ grid-template-columns: 3fr 2fr;
207
+ grid-template-rows: auto;
208
+
209
+ @media only screen and (max-width: $computer-width) {
210
+ display: flex;
211
+ padding-right: 0;
212
+ padding-left: 0;
213
+ aspect-ratio: auto;
214
+ gap: 0;
215
+ }
216
+
217
+ &.has--slider--flagAlign--right {
218
+ padding-right: 130px;
219
+ grid-template-areas: 'images content';
220
+ grid-template-columns: 3fr 2fr;
221
+ @media only screen and (max-width: $computer-width) {
222
+ padding-right: 0;
223
+ }
224
+ }
225
+ &.has--slider--flagAlign--left {
226
+ padding-left: 130px;
227
+ grid-template-areas: 'content images';
228
+ grid-template-columns: 2fr 3fr;
229
+ @media only screen and (max-width: $computer-width) {
230
+ padding-left: 0;
231
+ }
232
+ }
233
+
234
+ .highlight-image-wrapper {
235
+ grid-area: images;
236
+ img {
237
+ aspect-ratio: var(
238
+ --image-aspect-ratio,
239
+ $sliderImagesAspectRatio
240
+ ) !important;
241
+
242
+ @media only screen and (max-width: $computer-width) {
243
+ width: 100%;
244
+ }
245
+ }
246
+ }
247
+
248
+ .teaser-item-title {
249
+ position: relative;
250
+ top: 0;
251
+ width: 100%;
252
+ align-self: center;
253
+ padding: 0;
254
+ background: none;
255
+ color: white;
256
+ grid-area: content;
257
+ transform: none;
258
+
259
+ @media only screen and (max-width: $computer-width) {
260
+ position: relative;
261
+ width: 100%;
262
+ height: 100%;
263
+ padding: 60px 20px;
264
+ background: $black;
265
+ transform: none;
266
+ }
267
+ }
268
+ }
269
+ .slider-button {
270
+ width: 130px;
271
+ background: rgba(0, 0, 0, 0);
272
+ svg.icon {
273
+ width: 50px !important;
274
+ height: 50px !important;
275
+ padding: 40px;
276
+ background: rgba(0, 0, 0, 0.15);
277
+ }
278
+ }
279
+ }
280
+
281
+ &.full-height {
282
+ .teaser-item {
283
+ display: grid;
284
+ aspect-ratio: 16/9;
285
+ background: rgba(0, 0, 0, 0.75);
286
+ grid-template-areas: 'images content';
287
+ grid-template-columns: 1fr 1fr;
288
+ grid-template-rows: auto;
289
+
290
+ @media only screen and (max-width: $computer-width) {
291
+ display: flex;
292
+ padding-right: 0;
293
+ padding-left: 0;
294
+ aspect-ratio: auto;
295
+ }
296
+
297
+ &.has--slider--flagAlign--right {
298
+ grid-template-areas: 'images content';
299
+ .teaser-item-title {
300
+ padding-left: 74px; //Adding gap between the image & content
301
+ @media only screen and (max-width: $computer-width) {
302
+ padding-left: 20px;
303
+ }
304
+ }
305
+ }
306
+ &.has--slider--flagAlign--left {
307
+ grid-template-areas: 'content images';
308
+ .teaser-item-title {
309
+ padding-right: 74px; //Adding gap between the image & content
310
+ @media only screen and (max-width: $computer-width) {
311
+ padding-right: 20px;
312
+ }
313
+ }
314
+ }
315
+
316
+ .highlight-image-wrapper {
317
+ grid-area: images;
318
+
319
+ img {
320
+ aspect-ratio: var(
321
+ --image-aspect-ratio,
322
+ $sliderImagesAspectRatio
323
+ ) !important;
324
+
325
+ @media only screen and (max-width: $computer-width) {
326
+ width: 100%;
327
+ }
328
+ }
329
+ }
330
+ .teaser-item-title {
331
+ position: relative;
332
+ top: 0;
333
+ width: 100%;
334
+ align-self: center;
335
+ padding: $spacing-medium 130px;
336
+ background: none;
337
+ color: white;
338
+ grid-area: content;
339
+
340
+ transform: translateY(0);
341
+
342
+ @media only screen and (max-width: $computer-width) {
343
+ position: relative;
344
+ width: 100%;
345
+ height: 100%;
346
+ padding: 60px 20px;
347
+ background: $black;
348
+ transform: none;
349
+ }
350
+ }
351
+ }
352
+ .slider-button {
353
+ width: 130px;
354
+ background: rgba(0, 0, 0, 0);
355
+
356
+ svg.icon {
357
+ width: 50px !important;
358
+ height: 50px !important;
359
+ padding: 40px;
360
+ background: rgba(0, 0, 0, 0.15);
361
+ }
362
+ }
363
+ }
115
364
  }